8 Commits

Author SHA1 Message Date
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
7 changed files with 150 additions and 10 deletions

View File

@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## Unreleased
## v0.5.0 - 05-08-2022
### Added
- path params are auto generated if not set
## v0.4.0 - 02-08-2022
### Changed

View File

@@ -101,7 +101,37 @@ 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

4
go.mod
View File

@@ -8,7 +8,7 @@ require (
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.5.0
github.com/invopop/jsonschema v0.6.0
github.com/labstack/echo/v4 v4.7.2
github.com/mailru/easyjson v0.7.7 // indirect
github.com/stretchr/testify v1.8.0
@@ -17,7 +17,7 @@ require (
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/go-openapi/jsonpointer v0.19.5 // indirect
github.com/invopop/yaml v0.1.0 // 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

7
go.sum
View File

@@ -17,10 +17,11 @@ github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB7
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.5.0 h1:6tvpBcwTGxzvx3M9f3IfzqQVyZvoH+0NRUtBcsgyfrU=
github.com/invopop/jsonschema v0.5.0/go.mod h1:O9uiLokuu0+MGFlyiaqtWxwqJm41/+8Nj0lD7A36YH0=
github.com/invopop/yaml v0.1.0 h1:YW3WGUoJEXYfzWBjn00zIlrw7brGVD0fUKRYDPAPhrc=
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=

View File

@@ -5,6 +5,7 @@ import (
"fmt"
"path"
"sort"
"strings"
"github.com/davidebianchi/gswagger/apirouter"
"github.com/getkin/kin-openapi/openapi3"
@@ -54,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
@@ -100,7 +103,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)
}
@@ -255,3 +258,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) {

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": ""
}
}
}
}
}
}