71 Commits

Author SHA1 Message Date
Davide Bianchi
24dfb293ea Upgrade version to v0.6.0 2022-11-04 15:15:01 +01:00
Davide Bianchi
a5b9bd3dc4 Merge pull request #86 from davidebianchi/feat/tags-support-in-add-routes 2022-11-04 15:10:02 +01:00
Federico Maggi
7f7c92eaca feat: tags support 2022-11-04 15:01:26 +01:00
Davide Bianchi
9fac38a162 fix 2022-10-03 09:18:13 +02:00
Davide Bianchi
424779a7d8 Upgrade version to v0.5.1 2022-10-03 09:17:33 +02:00
Davide Bianchi
d6a528ea28 fix: changelog 2022-10-03 09:17:25 +02:00
Davide Bianchi
909c58608a upgrade deps 2022-10-03 09:17:02 +02:00
Davide Bianchi
43c6e37a47 Merge pull request #78 from davidebianchi/dependabot/go_modules/github.com/getkin/kin-openapi-0.103.0 2022-10-03 09:14:37 +02:00
dependabot[bot]
b9dc8ff83c chore(deps): bump github.com/getkin/kin-openapi from 0.102.0 to 0.103.0
Bumps [github.com/getkin/kin-openapi](https://github.com/getkin/kin-openapi) from 0.102.0 to 0.103.0.
- [Release notes](https://github.com/getkin/kin-openapi/releases)
- [Commits](https://github.com/getkin/kin-openapi/compare/v0.102.0...v0.103.0)

---
updated-dependencies:
- dependency-name: github.com/getkin/kin-openapi
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-22 03:20:06 +00:00
Davide Bianchi
1b95853d11 Merge pull request #77 from davidebianchi/dependabot/go_modules/github.com/getkin/kin-openapi-0.102.0 2022-09-20 21:44:58 +02:00
Davide Bianchi
e8369933fc Merge pull request #74 from davidebianchi/dependabot/go_modules/github.com/labstack/echo/v4-4.9.0 2022-09-20 21:44:24 +02:00
dependabot[bot]
89d668771a chore(deps): bump github.com/getkin/kin-openapi from 0.98.0 to 0.102.0
Bumps [github.com/getkin/kin-openapi](https://github.com/getkin/kin-openapi) from 0.98.0 to 0.102.0.
- [Release notes](https://github.com/getkin/kin-openapi/releases)
- [Commits](https://github.com/getkin/kin-openapi/compare/v0.98.0...v0.102.0)

---
updated-dependencies:
- dependency-name: github.com/getkin/kin-openapi
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-19 03:08:43 +00:00
dependabot[bot]
0039a3f74f chore(deps): bump github.com/labstack/echo/v4 from 4.7.2 to 4.9.0
Bumps [github.com/labstack/echo/v4](https://github.com/labstack/echo) from 4.7.2 to 4.9.0.
- [Release notes](https://github.com/labstack/echo/releases)
- [Changelog](https://github.com/labstack/echo/blob/master/CHANGELOG.md)
- [Commits](https://github.com/labstack/echo/compare/v4.7.2...v4.9.0)

---
updated-dependencies:
- dependency-name: github.com/labstack/echo/v4
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-05 13:15:57 +00:00
Davide Bianchi
b29887d15f docs: update CHANGELOG 2022-08-05 17:56:20 +02:00
Davide Bianchi
e03aeb51c2 update deps 2022-08-05 17:55:39 +02:00
Davide Bianchi
a3cb8e3775 Merge pull request #68 from davidebianchi/dependabot/go_modules/github.com/invopop/jsonschema-0.6.0 2022-08-05 17:54:31 +02:00
Davide Bianchi
995c3d97a2 Merge pull request #70 from davidebianchi/autofill-path-params 2022-08-05 17:52:46 +02:00
Davide Bianchi
d376b5411e Update README.md 2022-08-05 17:48:09 +02:00
Davide Bianchi
b187bd716f docs: update CHANGELOG 2022-08-05 17:44:50 +02:00
Davide Bianchi
d07b9c96f5 feat: autofill path params 2022-08-05 17:35:30 +02:00
dependabot[bot]
3c8cffc622 chore(deps): bump github.com/invopop/jsonschema from 0.5.0 to 0.6.0
Bumps [github.com/invopop/jsonschema](https://github.com/invopop/jsonschema) from 0.5.0 to 0.6.0.
- [Release notes](https://github.com/invopop/jsonschema/releases)
- [Commits](https://github.com/invopop/jsonschema/compare/v0.5.0...v0.6.0)

---
updated-dependencies:
- dependency-name: github.com/invopop/jsonschema
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-08-04 03:12:40 +00:00
Davide Bianchi
c5e3219f7a docs: update CHANGELOG 2022-08-02 09:15:52 +02:00
Davide Bianchi
d9c105585b Merge pull request #53 from davidebianchi/upgrade-deps 2022-08-02 09:13:59 +02:00
Davide Bianchi
3f7d09cc36 improve changelog 2022-08-02 09:11:28 +02:00
Davide Bianchi
57842cf39d upgrade deps 2022-08-02 09:08:04 +02:00
Davide Bianchi
3e359451c8 Merge pull request #66 from davidebianchi/dependabot/go_modules/github.com/stretchr/testify-1.8.0 2022-08-01 08:58:28 +02:00
dependabot[bot]
7896d8efd3 chore(deps): bump github.com/stretchr/testify from 1.7.5 to 1.8.0
Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.7.5 to 1.8.0.
- [Release notes](https://github.com/stretchr/testify/releases)
- [Commits](https://github.com/stretchr/testify/compare/v1.7.5...v1.8.0)

---
updated-dependencies:
- dependency-name: github.com/stretchr/testify
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-30 03:16:40 +00:00
Davide Bianchi
ac9ae09ff9 Merge pull request #57 from davidebianchi/dependabot/go_modules/github.com/labstack/echo/v4-4.7.2
chore(deps): bump github.com/labstack/echo/v4 from 4.6.3 to 4.7.2
2022-06-25 08:29:04 +02:00
dependabot[bot]
42bfc9c9a6 chore(deps): bump github.com/labstack/echo/v4 from 4.6.3 to 4.7.2
Bumps [github.com/labstack/echo/v4](https://github.com/labstack/echo) from 4.6.3 to 4.7.2.
- [Release notes](https://github.com/labstack/echo/releases)
- [Changelog](https://github.com/labstack/echo/blob/master/CHANGELOG.md)
- [Commits](https://github.com/labstack/echo/compare/v4.6.3...v4.7.2)

---
updated-dependencies:
- dependency-name: github.com/labstack/echo/v4
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-25 06:23:31 +00:00
Davide Bianchi
32233b0a6b Merge pull request #65 from davidebianchi/dependabot/go_modules/github.com/stretchr/testify-1.7.5
chore(deps): bump github.com/stretchr/testify from 1.7.2 to 1.7.5
2022-06-25 08:22:06 +02:00
dependabot[bot]
ab052edbe2 chore(deps): bump github.com/stretchr/testify from 1.7.2 to 1.7.5
Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.7.2 to 1.7.5.
- [Release notes](https://github.com/stretchr/testify/releases)
- [Commits](https://github.com/stretchr/testify/compare/v1.7.2...v1.7.5)

---
updated-dependencies:
- dependency-name: github.com/stretchr/testify
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-24 03:09:17 +00:00
Davide Bianchi
90b7305b57 Merge pull request #62 from davidebianchi/dependabot/go_modules/github.com/stretchr/testify-1.7.2
chore(deps): bump github.com/stretchr/testify from 1.7.0 to 1.7.2
2022-06-18 23:53:57 +02:00
dependabot[bot]
0a6ddb22c3 chore(deps): bump github.com/stretchr/testify from 1.7.0 to 1.7.2
Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.7.0 to 1.7.2.
- [Release notes](https://github.com/stretchr/testify/releases)
- [Commits](https://github.com/stretchr/testify/compare/v1.7.0...v1.7.2)

---
updated-dependencies:
- dependency-name: github.com/stretchr/testify
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-07 03:11:22 +00:00
Davide Bianchi
e884893fd5 chore: remove support to go 1.15 2022-03-26 18:34:24 +01:00
Davide Bianchi
1aaf503686 upgrade deps 2022-03-26 18:20:16 +01:00
Davide Bianchi
f109edd60a feat: upgrade deps 2022-03-12 19:13:02 +01:00
Davide Bianchi
d187894847 Merge pull request #49 from davidebianchi/dependabot/go_modules/github.com/getkin/kin-openapi-0.89.0 2022-02-04 09:52:46 +01:00
dependabot[bot]
6eeb5ab409 chore(deps): bump github.com/getkin/kin-openapi from 0.88.0 to 0.89.0
Bumps [github.com/getkin/kin-openapi](https://github.com/getkin/kin-openapi) from 0.88.0 to 0.89.0.
- [Release notes](https://github.com/getkin/kin-openapi/releases)
- [Commits](https://github.com/getkin/kin-openapi/compare/v0.88.0...v0.89.0)

---
updated-dependencies:
- dependency-name: github.com/getkin/kin-openapi
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-04 03:12:31 +00:00
Davide Bianchi
8efc400a2f Merge pull request #48 from davidebianchi/dependabot/go_modules/github.com/labstack/echo/v4-4.6.3 2022-02-02 22:41:50 +01:00
dependabot[bot]
5c5d02c68e chore(deps): bump github.com/labstack/echo/v4 from 4.6.1 to 4.6.3
Bumps [github.com/labstack/echo/v4](https://github.com/labstack/echo) from 4.6.1 to 4.6.3.
- [Release notes](https://github.com/labstack/echo/releases)
- [Changelog](https://github.com/labstack/echo/blob/master/CHANGELOG.md)
- [Commits](https://github.com/labstack/echo/compare/v4.6.1...v4.6.3)

---
updated-dependencies:
- dependency-name: github.com/labstack/echo/v4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-11 03:16:28 +00:00
Davide Bianchi
e5b47a772a Merge pull request #46 from davidebianchi/dependabot/go_modules/github.com/getkin/kin-openapi-0.88.0 2022-01-05 18:25:13 +01:00
dependabot[bot]
fa6f33399b chore(deps): bump github.com/getkin/kin-openapi from 0.87.0 to 0.88.0
Bumps [github.com/getkin/kin-openapi](https://github.com/getkin/kin-openapi) from 0.87.0 to 0.88.0.
- [Release notes](https://github.com/getkin/kin-openapi/releases)
- [Commits](https://github.com/getkin/kin-openapi/compare/v0.87.0...v0.88.0)

---
updated-dependencies:
- dependency-name: github.com/getkin/kin-openapi
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-05 03:13:39 +00:00
Davide Bianchi
786a5ed67d Merge pull request #45 from davidebianchi/echo-integration-example 2022-01-04 15:40:12 +01:00
Davide Bianchi
8f8ca16724 test: add subrouter test 2021-12-27 19:45:53 +01:00
Davide Bianchi
e1e3e95d80 feat: add test of integration of echo router 2021-12-22 19:13:18 +01:00
Davide Bianchi
1f550922b6 Merge pull request #44 from davidebianchi/dependabot/go_modules/github.com/getkin/kin-openapi-0.87.0 2021-12-21 22:57:20 +01:00
dependabot[bot]
55cfa361ce chore(deps): bump github.com/getkin/kin-openapi from 0.86.0 to 0.87.0
Bumps [github.com/getkin/kin-openapi](https://github.com/getkin/kin-openapi) from 0.86.0 to 0.87.0.
- [Release notes](https://github.com/getkin/kin-openapi/releases)
- [Commits](https://github.com/getkin/kin-openapi/compare/v0.86.0...v0.87.0)

---
updated-dependencies:
- dependency-name: github.com/getkin/kin-openapi
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-21 03:09:22 +00:00
Davide Bianchi
0c867d2839 fix: change test name 2021-12-20 20:32:39 +01:00
Davide Bianchi
68fdf59cdb change go version to 1.17 and update workflow to support from go version 1.15 to 1.17 2021-12-20 20:31:46 +01:00
Davide Bianchi
ebb8822041 Merge pull request #42 from davidebianchi/dependabot/go_modules/github.com/getkin/kin-openapi-0.86.0 2021-12-20 20:28:23 +01:00
Davide Bianchi
491f683807 fix: update CHANGELOG 2021-12-20 20:25:58 +01:00
Davide Bianchi
122be38154 Merge pull request #39 from danibix95/fix/align-code-docs 2021-12-20 20:21:53 +01:00
dependabot[bot]
a0ea89ed92 chore(deps): bump github.com/getkin/kin-openapi from 0.85.0 to 0.86.0
Bumps [github.com/getkin/kin-openapi](https://github.com/getkin/kin-openapi) from 0.85.0 to 0.86.0.
- [Release notes](https://github.com/getkin/kin-openapi/releases)
- [Commits](https://github.com/getkin/kin-openapi/compare/v0.85.0...v0.86.0)

---
updated-dependencies:
- dependency-name: github.com/getkin/kin-openapi
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-13 03:14:25 +00:00
Davide Bianchi
f21942de1b Merge pull request #41 from davidebianchi/dependabot/go_modules/github.com/getkin/kin-openapi-0.85.0 2021-12-06 22:34:19 +01:00
dependabot[bot]
b1b7025862 chore(deps): bump github.com/getkin/kin-openapi from 0.79.0 to 0.85.0
Bumps [github.com/getkin/kin-openapi](https://github.com/getkin/kin-openapi) from 0.79.0 to 0.85.0.
- [Release notes](https://github.com/getkin/kin-openapi/releases)
- [Commits](https://github.com/getkin/kin-openapi/compare/v0.79.0...v0.85.0)

---
updated-dependencies:
- dependency-name: github.com/getkin/kin-openapi
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-06 03:12:57 +00:00
danibix95
3d21dece34 Set method as first parameter of AddRoute function in Router interface 2021-11-23 23:19:52 +01:00
Davide Bianchi
715c554482 docs: update README 2021-11-10 11:26:34 +01:00
Davide Bianchi
d35432abaf test: add integration test 2021-11-10 11:19:12 +01:00
Davide Bianchi
ffb0e6b3f7 docs: update CHANGELOG 2021-11-10 10:41:38 +01:00
Davide Bianchi
94abd8f4bf docs: update README 2021-11-10 10:39:59 +01:00
Davide Bianchi
7232d5d823 feat: add coverage report 2021-11-10 10:34:38 +01:00
Davide Bianchi
b26ddbeecf Update test-builds.yml 2021-11-10 10:30:40 +01:00
Davide Bianchi
3374e2bd80 Merge pull request #36 from davidebianchi/feat/subrouter-path-prefix 2021-11-10 10:27:22 +01:00
Davide Bianchi
33d81e9cdd docs: update CHANGELOG 2021-11-10 10:23:17 +01:00
Davide Bianchi
a7a671be5a test: add route with path equal to prefix path 2021-11-10 10:22:45 +01:00
Davide Bianchi
239a70a1a0 test: more simple test 2021-11-10 10:15:55 +01:00
Davide Bianchi
8c0aacb68c fix: remove GetSwaggerSchema fn 2021-11-10 10:13:51 +01:00
Davide Bianchi
d145c6ca5d feat: add SubRouter method 2021-11-10 10:12:26 +01:00
Davide Bianchi
a8c5be8870 feat: add SubRouter method 2021-11-10 10:02:32 +01:00
Davide Bianchi
8fda85d9d3 docs: update CHANGELOG 2021-11-09 22:36:56 +01:00
Davide Bianchi
a872dd02b7 feat: add support to subrouter, handle path prefix 2021-11-09 22:35:17 +01:00
21 changed files with 743 additions and 78 deletions

View File

@@ -5,28 +5,35 @@ on:
push:
jobs:
tests:
name: Test on go ${{ matrix.go_version }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
go_version: [1.15]
os: [macos-latest, ubuntu-latest]
steps:
- uses: actions/checkout@v1
- name: Use golang ${{ matrix.go_version }}
uses: actions/setup-go@v1
with:
go-version: ${{ matrix.go_version }}
name: Test on go ${{ matrix.go_version }} os ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
go_version: [1.16, 1.17]
os: [ubuntu-latest]
include:
- go_version: 1.17
os: macos-latest
steps:
- uses: actions/checkout@v1
- name: Use golang ${{ matrix.go_version }}
uses: actions/setup-go@v1
with:
go-version: ${{ matrix.go_version }}
- name: Go version
run: |
go version
- name: Go get dependencies
run: |
go get -v -t -d ./...
- name: Run tests
run: |
go test ./... -count=1 -race -cover
- name: Build
run: |
go build -v .
- name: Go version
run: |
go version
- name: Go get dependencies
run: |
go get -v -t -d ./...
- name: Run tests
run: |
go test ./... -count=1 -race -cover -coverprofile cover.out
- name: Build
run: |
go build -v .
- name: Send the coverage output
uses: shogo82148/actions-goveralls@v1
with:
path-to-profile: cover.out

View File

@@ -5,6 +5,66 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## Unreleased
## 0.6.0 - 04-11-2022
### Added
- Tags support to `router.AddRoute` accepted definition
## 0.5.1 - 03-10-2022
### Fixed
- upgrade deps
## v0.5.0 - 05-08-2022
### Added
- path params are auto generated if not set
## v0.4.0 - 02-08-2022
### Changed
- change jsonschema lib to `invopop/jsonschema v0.5.0`. This updates remove the `additionalProperties: true` from all the schemas, as it is the default value
### BREAKING CHANGES
- modified Router interface by sorting addRoute arguments in a different manner: first method and then path
To migrate, all the router implementation must be updated with the Router interface change.
Before:
```go
type Router interface {
AddRoute(path, method string, handler HandlerFunc) Route
}
```
After:
```go
type Router interface {
AddRoute(method, path string, handler HandlerFunc) Route
}
```
### Updates
- kin-openapi@v0.98.0
- go-openapi/swag@v0.21.1
- labstack/echo/v4@v4.7.2
## v0.3.0 - 10-11-2021
### Added
- handle router with path prefix
- add SubRouter method to use a new sub router
## v0.2.0 - 16-10-2021
### BREAKING CHANGES

24
Makefile Normal file
View File

@@ -0,0 +1,24 @@
VERSION ?= latest
# Create a variable that contains the current date in UTC
# Different flow if this script is running on Darwin or Linux machines.
ifeq (Darwin,$(shell uname))
NOW_DATE = $(shell date -u +%d-%m-%Y)
else
NOW_DATE = $(shell date -u -I)
endif
all: test
.PHONY: test
test:
go test ./... -coverprofile coverage.out
$(MAKE) clean
.PHONY: version
version:
sed -i.bck "s|## Unreleased|## Unreleased\n\n## ${VERSION} - ${NOW_DATE}|g" "CHANGELOG.md"
rm -fr "CHANGELOG.md.bck"
git add "CHANGELOG.md"
git commit -m "Upgrade version to v${VERSION}"
git tag v${VERSION}

View File

@@ -1,6 +1,7 @@
<div align="center">
[![Build Status][github-actions-svg]][github-actions]
[![Coverage Status](https://coveralls.io/repos/github/davidebianchi/gswagger/badge.svg?branch=main)](https://coveralls.io/github/davidebianchi/gswagger?branch=main)
[![Go Report Card][go-report-card]][go-report-card-link]
[![GoDoc][godoc-svg]][godoc-link]
@@ -100,7 +101,46 @@ operation.AddRequestBody(requestBody)
router.AddRawRoute(http.MethodPost, "/cars", okHandler, operation)
```
This configuration will output the schema shown [here](testdata/users_employees.json)
This configuration will output the schema shown [here](testdata/users_employees.json).
## Auto generated path params schema
The path params, if not set in schema, are auto generated from the path. Currently, it is supported only the path params like `{myPath}`.
For example, with this use case:
```golang
okHandler := func(w http.ResponseWriter, req *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte("OK"))
}
_, err := router.AddRoute(http.MethodGet, "/users/{userId}", okHandler, Definitions{
Querystring: ParameterValue{
"query": {
Schema: &Schema{Value: ""},
},
},
})
require.NoError(t, err)
_, err = router.AddRoute(http.MethodGet, "/cars/{carId}/drivers/{driverId}", okHandler, Definitions{})
require.NoError(t, err)
```
The generated oas schema will contains `userId`, `carId` and `driverId` as path params set to string.
If only one params is set, you must specify manually all the path params.
The generated file for this test case is [here](./testdata/params-autofill.json).
## SubRouter
It is possible to create a new sub router from the swagger.Router.
It is possible to add a prefix to all the routes created under the specific router (instead of use the router specific methods, if given, or repeat the prefix for every route).
It could also be useful if you need a sub router to create a group of APIs which use the same middleware (for example,this could be achieved by the SubRouter features of gorilla mux, for example).
To see the SubRouter example, please see the [SubRouter test](./integration_test.go).
### FAQ
@@ -129,7 +169,7 @@ see the [tags on this repository](https://github.com/davidebianchi/gswagger/tags
<!-- Reference -->
[kin-openapi]: https://github.com/getkin/kin-openapi
[jsonschema]: https://github.com/alecthomas/jsonschema
[jsonschema]: https://github.com/invopop/jsonschemaa
[github-actions]: https://github.com/davidebianchi/gswagger/actions
[github-actions-svg]: https://github.com/davidebianchi/gswagger/workflows/Test%20and%20build/badge.svg
[godoc-svg]: https://godoc.org/github.com/davidebianchi/gswagger?status.svg

View File

@@ -6,7 +6,7 @@ type gorillaRouter struct {
router *mux.Router
}
func (r gorillaRouter) AddRoute(path string, method string, handler HandlerFunc) Route {
func (r gorillaRouter) AddRoute(method string, path string, handler HandlerFunc) Route {
return r.router.HandleFunc(path, handler).Methods(method)
}

View File

@@ -18,7 +18,7 @@ func TestGorillaMuxRouter(t *testing.T) {
})
t.Run("add new route", func(t *testing.T) {
route := ar.AddRoute("/foo", http.MethodGet, func(w http.ResponseWriter, req *http.Request) {
route := ar.AddRoute(http.MethodGet, "/foo", func(w http.ResponseWriter, req *http.Request) {
w.WriteHeader(200)
w.Write(nil)
})

View File

@@ -6,7 +6,7 @@ import "net/http"
type HandlerFunc func(w http.ResponseWriter, req *http.Request)
type Router interface {
AddRoute(path string, method string, handler HandlerFunc) Route
AddRoute(method string, path string, handler HandlerFunc) Route
}
type Route interface{}

30
go.mod
View File

@@ -1,14 +1,34 @@
module github.com/davidebianchi/gswagger
go 1.15
go 1.17
require (
github.com/alecthomas/jsonschema v0.0.0-20210920000243-787cd8204a0d
github.com/getkin/kin-openapi v0.79.0
github.com/getkin/kin-openapi v0.103.0
github.com/ghodss/yaml v1.0.0
github.com/go-openapi/swag v0.19.15 // indirect
github.com/go-openapi/swag v0.21.1 // indirect
github.com/gorilla/mux v1.8.0
github.com/iancoleman/orderedmap v0.2.0 // indirect
github.com/invopop/jsonschema v0.6.0
github.com/labstack/echo/v4 v4.9.0
github.com/mailru/easyjson v0.7.7 // indirect
github.com/stretchr/testify v1.7.0
github.com/stretchr/testify v1.8.0
)
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/go-openapi/jsonpointer v0.19.5 // indirect
github.com/invopop/yaml v0.2.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/labstack/gommon v0.3.1 // indirect
github.com/mattn/go-colorable v0.1.12 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasttemplate v1.2.1 // indirect
golang.org/x/crypto v0.0.0-20220312131142-6068a2e6cfdc // indirect
golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5 // indirect
golang.org/x/text v0.3.7 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

65
go.sum
View File

@@ -1,23 +1,27 @@
github.com/alecthomas/jsonschema v0.0.0-20210920000243-787cd8204a0d h1:sUHuJQ3zwLmUgKM1v51WLWRtoy9r+hc/m7DoNftpUdA=
github.com/alecthomas/jsonschema v0.0.0-20210920000243-787cd8204a0d/go.mod h1:/n6+1/DWPltRLWL/VKyUxg6tzsl5kHUCcraimt4vr60=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/getkin/kin-openapi v0.79.0 h1:YLZIgIhZLq9z5WFHHIK+oWORRfn6jjwr7qN0xak0xbE=
github.com/getkin/kin-openapi v0.79.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg=
github.com/getkin/kin-openapi v0.103.0 h1:F5wAtaQvPWxKCAYZ69LgHAThgu16p4u41VQtbn1U8LA=
github.com/getkin/kin-openapi v0.103.0/go.mod h1:w4lRPHiyOdwGbOkLIyk+P0qCwlu7TXPCHD/64nSXzgE=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM=
github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
github.com/go-openapi/swag v0.21.1 h1:wm0rhTb5z7qpJRHBdPOMuY4QjVUMbF6/kwoYeRAOrKU=
github.com/go-openapi/swag v0.21.1/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0/go.mod h1:N0Wam8K1arqPXNWjMo21EXnBPOPp36vB07FNRdD2geA=
github.com/iancoleman/orderedmap v0.2.0 h1:sq1N/TFpYH++aViPcaKjys3bDClUEU7s5B+z6jq8pNA=
github.com/iancoleman/orderedmap v0.2.0/go.mod h1:N0Wam8K1arqPXNWjMo21EXnBPOPp36vB07FNRdD2geA=
github.com/invopop/jsonschema v0.6.0 h1:8e+xY8ZEn8gDHUYylSlLHy22P+SLeIRIHv3nM3hCbmY=
github.com/invopop/jsonschema v0.6.0/go.mod h1:O9uiLokuu0+MGFlyiaqtWxwqJm41/+8Nj0lD7A36YH0=
github.com/invopop/yaml v0.1.0/go.mod h1:2XuRLgs/ouIrW3XNzuNj7J3Nvu/Dig5MXvbCEdiBN3Q=
github.com/invopop/yaml v0.2.0 h1:7zky/qH+O0DwAyoobXUqvVBwgBFRxKoQ/3FjcVpjTMY=
github.com/invopop/yaml v0.2.0/go.mod h1:2XuRLgs/ouIrW3XNzuNj7J3Nvu/Dig5MXvbCEdiBN3Q=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
@@ -25,30 +29,73 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/labstack/echo/v4 v4.9.0 h1:wPOF1CE6gvt/kmbMR4dGzWvHMPT+sAEUJOwOTtvITVY=
github.com/labstack/echo/v4 v4.9.0/go.mod h1:xkCDAdFCIf8jsFQ5NnbK7oqaF/yU1A1X20Ltm0OvSks=
github.com/labstack/gommon v0.3.1 h1:OomWaJXm7xR6L1HmEtGyQf26TEn7V6X88mktX9kee9o=
github.com/labstack/gommon v0.3.1/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.3.1-0.20190311161405-34c6fa2dc709/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4=
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220312131142-6068a2e6cfdc h1:i6Z9eOQAdM7lvsbkT3fwFNtSAAC+A59TYilFj53HW+E=
golang.org/x/crypto v0.0.0-20220312131142-6068a2e6cfdc/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5 h1:y/woIyUBFbpQGKS0u1aHF/40WUDnek3fPOyD08H5Vng=
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@@ -12,6 +12,7 @@ import (
"github.com/davidebianchi/gswagger/apirouter"
"github.com/getkin/kin-openapi/openapi3"
"github.com/gorilla/mux"
"github.com/labstack/echo/v4"
"github.com/stretchr/testify/require"
)
@@ -22,7 +23,7 @@ const (
func TestIntegration(t *testing.T) {
t.Run("router works correctly", func(t *testing.T) {
muxRouter := setupSwagger(t)
muxRouter, _ := setupSwagger(t)
w := httptest.NewRecorder()
r := httptest.NewRequest(http.MethodGet, "/hello", nil)
@@ -46,6 +47,125 @@ func TestIntegration(t *testing.T) {
require.Equal(t, "{\"components\":{},\"info\":{\"title\":\"test swagger title\",\"version\":\"test swagger version\"},\"openapi\":\"3.0.0\",\"paths\":{\"/hello\":{\"get\":{\"responses\":{\"default\":{\"description\":\"\"}}}}}}", body)
})
})
t.Run("router works correctly - echo", func(t *testing.T) {
echoRouter, _ := setupEchoSwagger(t)
w := httptest.NewRecorder()
r := httptest.NewRequest(http.MethodGet, "/hello", nil)
echoRouter.ServeHTTP(w, r)
require.Equal(t, http.StatusOK, w.Result().StatusCode)
body := readBody(t, w.Result().Body)
require.Equal(t, "OK", body)
t.Run("and generate swagger", func(t *testing.T) {
w := httptest.NewRecorder()
r := httptest.NewRequest(http.MethodGet, swagger.DefaultJSONDocumentationPath, nil)
echoRouter.ServeHTTP(w, r)
require.Equal(t, http.StatusOK, w.Result().StatusCode)
body := readBody(t, w.Result().Body)
require.Equal(t, "{\"components\":{},\"info\":{\"title\":\"test swagger title\",\"version\":\"test swagger version\"},\"openapi\":\"3.0.0\",\"paths\":{\"/hello\":{\"get\":{\"responses\":{\"default\":{\"description\":\"\"}}}}}}", body)
})
})
t.Run("works correctly with subrouter - handles path prefix - gorilla mux", func(t *testing.T) {
muxRouter, swaggerRouter := setupSwagger(t)
muxSubRouter := muxRouter.NewRoute().Subrouter()
subRouter, err := swaggerRouter.SubRouter(apirouter.NewGorillaMuxRouter(muxSubRouter), swagger.SubRouterOptions{
PathPrefix: "/prefix",
})
require.NoError(t, err)
_, err = subRouter.AddRoute(http.MethodGet, "/foo", okHandler, swagger.Definitions{})
require.NoError(t, err)
w := httptest.NewRecorder()
r := httptest.NewRequest(http.MethodGet, "/hello", nil)
muxRouter.ServeHTTP(w, r)
require.Equal(t, http.StatusOK, w.Result().StatusCode)
body := readBody(t, w.Result().Body)
require.Equal(t, "OK", body)
t.Run("correctly call sub router", func(t *testing.T) {
w := httptest.NewRecorder()
r := httptest.NewRequest(http.MethodGet, "/prefix/foo", nil)
muxRouter.ServeHTTP(w, r)
require.Equal(t, http.StatusOK, w.Result().StatusCode)
body := readBody(t, w.Result().Body)
require.Equal(t, "OK", body)
})
t.Run("and generate swagger", func(t *testing.T) {
w := httptest.NewRecorder()
r := httptest.NewRequest(http.MethodGet, swagger.DefaultJSONDocumentationPath, nil)
muxRouter.ServeHTTP(w, r)
require.Equal(t, http.StatusOK, w.Result().StatusCode)
body := readBody(t, w.Result().Body)
require.Equal(t, "{\"components\":{},\"info\":{\"title\":\"test swagger title\",\"version\":\"test swagger version\"},\"openapi\":\"3.0.0\",\"paths\":{\"/hello\":{\"get\":{\"responses\":{\"default\":{\"description\":\"\"}}}}}}", body)
})
})
t.Run("works correctly with subrouter - handles path prefix - echo", func(t *testing.T) {
eRouter, swaggerRouter := setupEchoSwagger(t)
subRouter, err := swaggerRouter.SubRouter(echoRouter{router: eRouter}, swagger.SubRouterOptions{
PathPrefix: "/prefix",
})
require.NoError(t, err)
_, err = subRouter.AddRoute(http.MethodGet, "/foo", okHandler, swagger.Definitions{})
require.NoError(t, err)
w := httptest.NewRecorder()
r := httptest.NewRequest(http.MethodGet, "/hello", nil)
eRouter.ServeHTTP(w, r)
require.Equal(t, http.StatusOK, w.Result().StatusCode)
body := readBody(t, w.Result().Body)
require.Equal(t, "OK", body)
t.Run("correctly call sub router", func(t *testing.T) {
w := httptest.NewRecorder()
r := httptest.NewRequest(http.MethodGet, "/prefix/foo", nil)
eRouter.ServeHTTP(w, r)
require.Equal(t, http.StatusOK, w.Result().StatusCode)
body := readBody(t, w.Result().Body)
require.Equal(t, "OK", body)
})
t.Run("and generate swagger", func(t *testing.T) {
w := httptest.NewRecorder()
r := httptest.NewRequest(http.MethodGet, swagger.DefaultJSONDocumentationPath, nil)
eRouter.ServeHTTP(w, r)
require.Equal(t, http.StatusOK, w.Result().StatusCode)
body := readBody(t, w.Result().Body)
require.Equal(t, "{\"components\":{},\"info\":{\"title\":\"test swagger title\",\"version\":\"test swagger version\"},\"openapi\":\"3.0.0\",\"paths\":{\"/hello\":{\"get\":{\"responses\":{\"default\":{\"description\":\"\"}}}}}}", body)
})
})
}
func readBody(t *testing.T, requestBody io.ReadCloser) string {
@@ -57,7 +177,7 @@ func readBody(t *testing.T, requestBody io.ReadCloser) string {
return string(body)
}
func setupSwagger(t *testing.T) *mux.Router {
func setupSwagger(t *testing.T) (*mux.Router, *swagger.Router) {
t.Helper()
context := context.Background()
@@ -74,17 +194,61 @@ func setupSwagger(t *testing.T) *mux.Router {
})
require.NoError(t, err)
handler := func(w http.ResponseWriter, req *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte(`OK`))
}
operation := swagger.Operation{}
_, err = router.AddRawRoute(http.MethodGet, "/hello", handler, operation)
_, err = router.AddRawRoute(http.MethodGet, "/hello", okHandler, operation)
require.NoError(t, err)
err = router.GenerateAndExposeSwagger()
require.NoError(t, err)
return muxRouter
return muxRouter, router
}
func okHandler(w http.ResponseWriter, req *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte(`OK`))
}
func setupEchoSwagger(t *testing.T) (*echo.Echo, *swagger.Router) {
t.Helper()
context := context.Background()
e := echo.New()
router, err := swagger.NewRouter(echoRouter{router: e}, swagger.Options{
Context: context,
Openapi: &openapi3.T{
Info: &openapi3.Info{
Title: swaggerOpenapiTitle,
Version: swaggerOpenapiVersion,
},
},
})
require.NoError(t, err)
operation := swagger.Operation{}
_, err = router.AddRawRoute(http.MethodGet, "/hello", func(w http.ResponseWriter, req *http.Request) {
ctx := e.NewContext(req, w)
echoOkHandler(ctx)
}, operation)
require.NoError(t, err)
err = router.GenerateAndExposeSwagger()
require.NoError(t, err)
return e, router
}
func echoOkHandler(c echo.Context) error {
return c.String(http.StatusOK, "OK")
}
type echoRouter struct {
router *echo.Echo
}
func (r echoRouter) AddRoute(method, path string, handler apirouter.HandlerFunc) apirouter.Route {
return r.router.Add(method, path, echo.WrapHandler(http.HandlerFunc(handler)))
}

23
main.go
View File

@@ -36,6 +36,7 @@ type Router struct {
context context.Context
jsonDocumentationPath string
yamlDocumentationPath string
pathPrefix string
}
// Options to be passed to create the new router and swagger
@@ -46,6 +47,8 @@ type Options struct {
JSONDocumentationPath string
// YAMLDocumentationPath is the path exposed by yaml endpoint. Default to /documentation/yaml.
YAMLDocumentationPath string
// Add path prefix to add to every router path.
PathPrefix string
}
// NewRouter generate new router with swagger. Default to OpenAPI 3.0.0
@@ -82,6 +85,22 @@ func NewRouter(router apirouter.Router, options Options) (*Router, error) {
context: ctx,
yamlDocumentationPath: yamlDocumentationPath,
jsonDocumentationPath: jsonDocumentationPath,
pathPrefix: options.PathPrefix,
}, nil
}
type SubRouterOptions struct {
PathPrefix string
}
func (r Router) SubRouter(router apirouter.Router, opts SubRouterOptions) (*Router, error) {
return &Router{
router: router,
swaggerSchema: r.swaggerSchema,
context: r.context,
jsonDocumentationPath: r.jsonDocumentationPath,
yamlDocumentationPath: r.yamlDocumentationPath,
pathPrefix: opts.PathPrefix,
}, nil
}
@@ -120,7 +139,7 @@ func (r Router) GenerateAndExposeSwagger() error {
if err != nil {
return fmt.Errorf("%w json marshal: %s", ErrGenerateSwagger, err)
}
r.router.AddRoute(r.jsonDocumentationPath, http.MethodGet, func(w http.ResponseWriter, req *http.Request) {
r.router.AddRoute(http.MethodGet, r.jsonDocumentationPath, func(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
w.Write(jsonSwagger)
@@ -130,7 +149,7 @@ func (r Router) GenerateAndExposeSwagger() error {
if err != nil {
return fmt.Errorf("%w yaml marshal: %s", ErrGenerateSwagger, err)
}
r.router.AddRoute(r.yamlDocumentationPath, http.MethodGet, func(w http.ResponseWriter, req *http.Request) {
r.router.AddRoute(http.MethodGet, r.yamlDocumentationPath, func(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "text/plain")
w.WriteHeader(http.StatusOK)
w.Write(yamlSwagger)

View File

@@ -17,7 +17,8 @@ import (
)
func TestNewRouter(t *testing.T) {
mRouter := apirouter.NewGorillaMuxRouter(mux.NewRouter())
muxRouter := mux.NewRouter()
mAPIRouter := apirouter.NewGorillaMuxRouter(muxRouter)
info := &openapi3.Info{
Title: "my title",
@@ -29,21 +30,21 @@ func TestNewRouter(t *testing.T) {
}
t.Run("not ok - invalid Openapi option", func(t *testing.T) {
r, err := NewRouter(mRouter, Options{})
r, err := NewRouter(mAPIRouter, Options{})
require.Nil(t, r)
require.EqualError(t, err, fmt.Sprintf("%s: swagger is required", ErrValidatingSwagger))
})
t.Run("ok - with default context", func(t *testing.T) {
r, err := NewRouter(mRouter, Options{
r, err := NewRouter(mAPIRouter, Options{
Openapi: openapi,
})
require.NoError(t, err)
require.Equal(t, &Router{
context: context.Background(),
router: mRouter,
router: mAPIRouter,
swaggerSchema: openapi,
jsonDocumentationPath: DefaultJSONDocumentationPath,
yamlDocumentationPath: DefaultYAMLDocumentationPath,
@@ -53,7 +54,7 @@ func TestNewRouter(t *testing.T) {
t.Run("ok - with custom context", func(t *testing.T) {
type key struct{}
ctx := context.WithValue(context.Background(), key{}, "value")
r, err := NewRouter(mRouter, Options{
r, err := NewRouter(mAPIRouter, Options{
Openapi: openapi,
Context: ctx,
})
@@ -61,7 +62,7 @@ func TestNewRouter(t *testing.T) {
require.NoError(t, err)
require.Equal(t, &Router{
context: ctx,
router: mRouter,
router: mAPIRouter,
swaggerSchema: openapi,
jsonDocumentationPath: DefaultJSONDocumentationPath,
yamlDocumentationPath: DefaultYAMLDocumentationPath,
@@ -71,7 +72,7 @@ func TestNewRouter(t *testing.T) {
t.Run("ok - with custom docs paths", func(t *testing.T) {
type key struct{}
ctx := context.WithValue(context.Background(), key{}, "value")
r, err := NewRouter(mRouter, Options{
r, err := NewRouter(mAPIRouter, Options{
Openapi: openapi,
Context: ctx,
JSONDocumentationPath: "/json/path",
@@ -81,7 +82,7 @@ func TestNewRouter(t *testing.T) {
require.NoError(t, err)
require.Equal(t, &Router{
context: ctx,
router: mRouter,
router: mAPIRouter,
swaggerSchema: openapi,
jsonDocumentationPath: "/json/path",
yamlDocumentationPath: "/yaml/path",
@@ -91,7 +92,7 @@ func TestNewRouter(t *testing.T) {
t.Run("ko - json documentation path does not start with /", func(t *testing.T) {
type key struct{}
ctx := context.WithValue(context.Background(), key{}, "value")
r, err := NewRouter(mRouter, Options{
r, err := NewRouter(mAPIRouter, Options{
Openapi: openapi,
Context: ctx,
JSONDocumentationPath: "json/path",
@@ -105,7 +106,7 @@ func TestNewRouter(t *testing.T) {
t.Run("ko - yaml documentation path does not start with /", func(t *testing.T) {
type key struct{}
ctx := context.WithValue(context.Background(), key{}, "value")
r, err := NewRouter(mRouter, Options{
r, err := NewRouter(mAPIRouter, Options{
Openapi: openapi,
Context: ctx,
JSONDocumentationPath: "/json/path",
@@ -315,6 +316,97 @@ func TestGenerateAndExposeSwagger(t *testing.T) {
require.NoError(t, err)
require.YAMLEq(t, string(expected), body, string(body))
})
t.Run("ok - subrouter", func(t *testing.T) {
mRouter := mux.NewRouter()
router, err := NewRouter(apirouter.NewGorillaMuxRouter(mRouter), Options{
Openapi: &openapi3.T{
Info: &openapi3.Info{
Title: "test swagger title",
Version: "test swagger version",
},
},
JSONDocumentationPath: "/custom/path",
})
require.NoError(t, err)
router.AddRoute(http.MethodGet, "/foo", func(w http.ResponseWriter, req *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte("ok"))
}, Definitions{})
mSubRouter := mRouter.PathPrefix("/prefix").Subrouter()
subrouter, err := router.SubRouter(apirouter.NewGorillaMuxRouter(mSubRouter), SubRouterOptions{
PathPrefix: "/prefix",
})
require.NoError(t, err)
_, err = subrouter.AddRoute(http.MethodGet, "/taz", func(w http.ResponseWriter, req *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte("ok"))
}, Definitions{})
require.NoError(t, err)
t.Run("add route with path equal to prefix path", func(t *testing.T) {
_, err = subrouter.AddRoute(http.MethodGet, "", func(w http.ResponseWriter, req *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte("ok"))
}, Definitions{})
require.NoError(t, err)
})
err = router.GenerateAndExposeSwagger()
require.NoError(t, err)
w := httptest.NewRecorder()
req := httptest.NewRequest(http.MethodGet, "/custom/path", nil)
mRouter.ServeHTTP(w, req)
require.Equal(t, http.StatusOK, w.Result().StatusCode)
require.True(t, strings.Contains(w.Result().Header.Get("content-type"), "application/json"))
body := readBody(t, w.Result().Body)
actual, err := ioutil.ReadFile("testdata/subrouter.json")
require.NoError(t, err)
require.JSONEq(t, string(actual), body)
})
t.Run("ok - new router with path prefix", func(t *testing.T) {
mRouter := mux.NewRouter()
router, err := NewRouter(apirouter.NewGorillaMuxRouter(mRouter), Options{
Openapi: &openapi3.T{
Info: &openapi3.Info{
Title: "test swagger title",
Version: "test swagger version",
},
},
JSONDocumentationPath: "/custom/path",
PathPrefix: "/prefix",
})
require.NoError(t, err)
router.AddRoute(http.MethodGet, "/foo", func(w http.ResponseWriter, req *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte("ok"))
}, Definitions{})
err = router.GenerateAndExposeSwagger()
require.NoError(t, err)
w := httptest.NewRecorder()
req := httptest.NewRequest(http.MethodGet, "/custom/path", nil)
mRouter.ServeHTTP(w, req)
require.Equal(t, http.StatusOK, w.Result().StatusCode)
require.True(t, strings.Contains(w.Result().Header.Get("content-type"), "application/json"))
body := readBody(t, w.Result().Body)
actual, err := ioutil.ReadFile("testdata/router_with_prefix.json")
require.NoError(t, err)
require.JSONEq(t, string(actual), body)
})
}
func readBody(t *testing.T, requestBody io.ReadCloser) string {

View File

@@ -3,11 +3,13 @@ package swagger
import (
"errors"
"fmt"
"path"
"sort"
"strings"
"github.com/alecthomas/jsonschema"
"github.com/davidebianchi/gswagger/apirouter"
"github.com/getkin/kin-openapi/openapi3"
"github.com/invopop/jsonschema"
)
var (
@@ -23,7 +25,7 @@ var (
// AddRawRoute add route to router with specific method, path and handler. Add the
// router also to the swagger schema, after validating it
func (r Router) AddRawRoute(method string, path string, handler apirouter.HandlerFunc, operation Operation) (interface{}, error) {
func (r Router) AddRawRoute(method string, routePath string, handler apirouter.HandlerFunc, operation Operation) (interface{}, error) {
op := operation.Operation
if op != nil {
err := operation.Validate(r.context)
@@ -36,10 +38,11 @@ func (r Router) AddRawRoute(method string, path string, handler apirouter.Handle
op.Responses = openapi3.NewResponses()
}
}
r.swaggerSchema.AddOperation(path, method, op)
pathWithPrefix := path.Join(r.pathPrefix, routePath)
r.swaggerSchema.AddOperation(pathWithPrefix, method, op)
// Handle, when content-type is json, the request/response marshalling? Maybe with a specific option.
return r.router.AddRoute(path, method, handler), nil
return r.router.AddRoute(method, pathWithPrefix, handler), nil
}
// Content is the type of a content.
@@ -52,14 +55,16 @@ type Schema struct {
AllowAdditionalProperties bool
}
// ParameterValue is the struct containing the schema or the content information.
// If content is specified, it takes precedence.
type ParameterValue map[string]struct {
type Parameter struct {
Content Content
Schema *Schema
Description string
}
// ParameterValue is the struct containing the schema or the content information.
// If content is specified, it takes precedence.
type ParameterValue map[string]Parameter
// ContentValue is the struct containing the content information.
type ContentValue struct {
Content Content
@@ -68,6 +73,7 @@ type ContentValue struct {
// Definitions of the route.
type Definitions struct {
Tags []string
PathParams ParameterValue
Querystring ParameterValue
Headers ParameterValue
@@ -87,6 +93,7 @@ const (
func (r Router) AddRoute(method string, path string, handler apirouter.HandlerFunc, schema Definitions) (interface{}, error) {
operation := NewOperation()
operation.Responses = make(openapi3.Responses)
operation.Tags = schema.Tags
err := r.resolveRequestBodySchema(schema.RequestBody, operation)
if err != nil {
@@ -98,7 +105,7 @@ func (r Router) AddRoute(method string, path string, handler apirouter.HandlerFu
return nil, fmt.Errorf("%w: %s", ErrResponses, err)
}
err = r.resolveParameterSchema(pathParamsType, schema.PathParams, operation)
err = r.resolveParameterSchema(pathParamsType, getPathParamsAutofilled(schema, path), operation)
if err != nil {
return nil, fmt.Errorf("%w: %s", ErrPathParams, err)
}
@@ -129,10 +136,11 @@ func (r Router) getSchemaFromInterface(v interface{}, allowAdditionalProperties
reflector := &jsonschema.Reflector{
DoNotReference: true,
AllowAdditionalProperties: allowAdditionalProperties,
Anonymous: true,
}
jsonSchema := reflector.Reflect(v)
jsonschema.Version = ""
jsonSchema.Version = ""
// Empty definitions. Definitions are not valid in openapi3, which use components.
// In the future, we could add an option to fill the components in openapi spec.
jsonSchema.Definitions = nil
@@ -252,3 +260,22 @@ func (r Router) addContentToOASSchema(content Content) (openapi3.Content, error)
}
return oasContent, nil
}
func getPathParamsAutofilled(schema Definitions, path string) ParameterValue {
if schema.PathParams == nil {
pathParams := strings.Split(path, "/")
for _, param := range pathParams {
if strings.HasPrefix(param, "{") && strings.HasSuffix(param, "}") {
if schema.PathParams == nil {
schema.PathParams = make(ParameterValue)
}
param = strings.Replace(param, "{", "", 1)
param = strings.Replace(param, "}", "", 1)
schema.PathParams[param] = Parameter{
Schema: &Schema{Value: ""},
}
}
}
}
return schema.PathParams
}

View File

@@ -184,6 +184,24 @@ func TestAddRoutes(t *testing.T) {
testPath: "/users/12",
fixturesPath: "testdata/params.json",
},
{
name: "schema without params autofilled",
routes: func(t *testing.T, router *Router) {
_, err := router.AddRoute(http.MethodGet, "/users/{userId}", okHandler, Definitions{
Querystring: ParameterValue{
"query": {
Schema: &Schema{Value: ""},
},
},
})
require.NoError(t, err)
_, err = router.AddRoute(http.MethodGet, "/cars/{carId}/drivers/{driverId}", okHandler, Definitions{})
require.NoError(t, err)
},
testPath: "/users/12",
fixturesPath: "testdata/params-autofill.json",
},
{
name: "schema with querystring",
routes: func(t *testing.T, router *Router) {
@@ -404,6 +422,17 @@ func TestAddRoutes(t *testing.T) {
testMethod: http.MethodPost,
fixturesPath: "testdata/oneOf.json",
},
{
name: "schema with tags",
routes: func(t *testing.T, router *Router) {
_, err := router.AddRoute(http.MethodGet, "/users", okHandler, Definitions{
Tags: []string{"Tag1", "Tag2"},
})
require.NoError(t, err)
},
testPath: "/users",
fixturesPath: "testdata/tags.json",
},
}
for _, test := range tests {
@@ -590,8 +619,7 @@ func TestResolveRequestBodySchema(t *testing.T) {
"type":"object",
"properties": {
"id": {"type": "string"}
},
"additionalProperties": true
}
}
}
}

View File

@@ -14,13 +14,11 @@
"multipart/form-data": {
"schema": {
"type": "object",
"additionalProperties": true,
"properties": {
"id": {
"type": "string"
},
"address": {
"additionalProperties": true,
"type": "object",
"properties": {
"street": {

1
testdata/oneOf.json vendored
View File

@@ -70,7 +70,6 @@
"type": "string"
},
"metadata": {
"additionalProperties": true,
"oneOf": [
{
"type": "string"

63
testdata/params-autofill.json vendored Normal file
View File

@@ -0,0 +1,63 @@
{
"components": {},
"info": {
"title": "test swagger title",
"version": "test swagger version"
},
"openapi": "3.0.0",
"paths": {
"/cars/{carId}/drivers/{driverId}": {
"get": {
"parameters": [
{
"in": "path",
"name": "carId",
"required": true,
"schema": {
"type": "string"
}
},
{
"in": "path",
"name": "driverId",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"default": {
"description": ""
}
}
}
},
"/users/{userId}": {
"get": {
"parameters": [
{
"in": "path",
"name": "userId",
"required": true,
"schema": {
"type": "string"
}
},
{
"in": "query",
"name": "query",
"schema": {
"type": "string"
}
}
],
"responses": {
"default": {
"description": ""
}
}
}
}
}
}

19
testdata/router_with_prefix.json vendored Normal file
View File

@@ -0,0 +1,19 @@
{
"components": {},
"info": {
"title": "test swagger title",
"version": "test swagger version"
},
"openapi": "3.0.0",
"paths": {
"/prefix/foo": {
"get": {
"responses": {
"default": {
"description": ""
}
}
}
}
}
}

View File

@@ -32,6 +32,7 @@
}
],
"requestBody": {
"content": {},
"description": "request body without schema"
},
"responses": {

37
testdata/subrouter.json vendored Normal file
View File

@@ -0,0 +1,37 @@
{
"components": {},
"info": {
"title": "test swagger title",
"version": "test swagger version"
},
"openapi": "3.0.0",
"paths": {
"/foo": {
"get": {
"responses": {
"default": {
"description": ""
}
}
}
},
"/prefix/taz": {
"get": {
"responses": {
"default": {
"description": ""
}
}
}
},
"/prefix": {
"get": {
"responses": {
"default": {
"description": ""
}
}
}
}
}
}

20
testdata/tags.json vendored Normal file
View File

@@ -0,0 +1,20 @@
{
"components": {},
"info": {
"title": "test swagger title",
"version": "test swagger version"
},
"openapi": "3.0.0",
"paths": {
"/users": {
"get": {
"tags": ["Tag1", "Tag2"],
"responses": {
"default": {
"description": ""
}
}
}
}
}
}