mirror of
https://github.com/davidebianchi/gswagger.git
synced 2026-01-07 06:38:38 -05:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b29887d15f | ||
|
|
e03aeb51c2 | ||
|
|
a3cb8e3775 | ||
|
|
995c3d97a2 | ||
|
|
d376b5411e | ||
|
|
b187bd716f | ||
|
|
d07b9c96f5 | ||
|
|
3c8cffc622 |
@@ -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
|
||||
|
||||
32
README.md
32
README.md
@@ -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
4
go.mod
@@ -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
7
go.sum
@@ -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=
|
||||
|
||||
30
route.go
30
route.go
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
63
testdata/params-autofill.json
vendored
Normal 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": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user