feat: add support to multiple params (#162)

This commit is contained in:
Davide Bianchi
2024-08-07 16:24:59 +02:00
committed by GitHub
parent 1802f29ad3
commit 3563d41c0f
5 changed files with 119 additions and 31 deletions

19
go.mod
View File

@@ -3,18 +3,13 @@ module github.com/davidebianchi/gswagger
go 1.20
require (
github.com/getkin/kin-openapi v0.125.0
github.com/getkin/kin-openapi v0.126.0
github.com/ghodss/yaml v1.0.0
github.com/go-openapi/swag v0.22.8 // indirect
github.com/gorilla/mux v1.8.1
github.com/labstack/echo/v4 v4.12.0
github.com/mailru/easyjson v0.7.7 // indirect
github.com/stretchr/testify v1.9.0
)
require (
github.com/gofiber/fiber/v2 v2.52.5
github.com/gorilla/mux v1.8.1
github.com/invopop/jsonschema v0.12.0
github.com/labstack/echo/v4 v4.12.0
github.com/stretchr/testify v1.9.0
)
require (
@@ -22,12 +17,14 @@ require (
github.com/bahlo/generic-list-go v0.2.0 // indirect
github.com/buger/jsonparser v1.1.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/go-openapi/jsonpointer v0.20.2 // indirect
github.com/go-openapi/jsonpointer v0.21.0 // indirect
github.com/go-openapi/swag v0.23.0 // indirect
github.com/google/uuid v1.5.0 // indirect
github.com/invopop/yaml v0.2.0 // indirect
github.com/invopop/yaml v0.3.1 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/klauspost/compress v1.17.0 // indirect
github.com/labstack/gommon v0.4.2 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect

17
go.sum
View File

@@ -6,14 +6,14 @@ github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMU
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
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.125.0 h1:jyQCyf2qXS1qvs2U00xQzkGCqYPhEhZDmSmVt65fXno=
github.com/getkin/kin-openapi v0.125.0/go.mod h1:wb1aSZA/iWmorQP9KTAS/phLj/t17B5jT7+fS8ed9NM=
github.com/getkin/kin-openapi v0.126.0 h1:c2cSgLnAsS0xYfKsgt5oBV6MYRM/giU8/RtwUY4wyfY=
github.com/getkin/kin-openapi v0.126.0/go.mod h1:7mONz8IwmSRg6RttPu6v8U/OJ+gr+J99qSFNjPGSQqw=
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.20.2 h1:mQc3nmndL8ZBzStEo3JYF8wzmeWffDH4VbXz58sAx6Q=
github.com/go-openapi/jsonpointer v0.20.2/go.mod h1:bHen+N0u1KEO3YlmqOjTT9Adn1RfD91Ar825/PuiRVs=
github.com/go-openapi/swag v0.22.8 h1:/9RjDSQ0vbFR+NyjGMkFTsA1IA0fmhKSThmfGZjicbw=
github.com/go-openapi/swag v0.22.8/go.mod h1:6QT22icPLEqAM/z/TChgb4WAveCHF92+2gF0CNjHpPI=
github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM=
github.com/gofiber/fiber/v2 v2.52.5 h1:tWoP1MJQjGEe4GB5TUGOi7P2E0ZMMRx5ZTG4rT+yGMo=
github.com/gofiber/fiber/v2 v2.52.5/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ=
@@ -23,8 +23,8 @@ github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
github.com/invopop/jsonschema v0.12.0 h1:6ovsNSuvn9wEQVOyc72aycBMVQFKz7cPdMJn10CvzRI=
github.com/invopop/jsonschema v0.12.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0=
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/invopop/yaml v0.3.1 h1:f0+ZpmhfBSS4MhG+4HYseMdJhoeeopbSKbq5Rpeelso=
github.com/invopop/yaml v0.3.1/go.mod h1:PMOp3nn4/12yEZUFfmOuNHJsZToEEOwoWsT+D81KkeA=
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/klauspost/compress v1.17.0 h1:Rnbp4K9EjcDuVuHtd0dgA4qNuv9yKDYKK1ulpJwgrqM=
@@ -80,6 +80,5 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
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/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

@@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"path"
"regexp"
"sort"
"strings"
@@ -289,15 +290,18 @@ func (r Router[_, _]) addContentToOASSchema(content Content) (openapi3.Content,
func getPathParamsAutoComplete(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{
re := regexp.MustCompile(`\{([^}]+)\}`)
segments := strings.Split(path, "/")
for _, segment := range segments {
params := re.FindAllStringSubmatch(segment, -1)
if len(params) == 0 {
continue
}
if schema.PathParams == nil {
schema.PathParams = make(ParameterValue)
}
for _, param := range params {
schema.PathParams[param[1]] = Parameter{
Schema: &Schema{Value: ""},
}
}

View File

@@ -187,7 +187,7 @@ func TestAddRoutes(t *testing.T) {
fixturesPath: "testdata/params.json",
},
{
name: "schema without params autofilled",
name: "schema without explicit params autofill them",
routes: func(t *testing.T, router *TestRouter) {
_, err := router.AddRoute(http.MethodGet, "/users/{userId}", okHandler, Definitions{
Querystring: ParameterValue{
@@ -200,8 +200,11 @@ func TestAddRoutes(t *testing.T) {
_, err = router.AddRoute(http.MethodGet, "/cars/{carId}/drivers/{driverId}", okHandler, Definitions{})
require.NoError(t, err)
_, err = router.AddRoute(http.MethodGet, "/files/{name}.{extension}", okHandler, Definitions{})
require.NoError(t, err)
},
testPath: "/users/12",
testPath: "/files/myid.yaml",
fixturesPath: "testdata/params-autofill.json",
},
{
@@ -1118,3 +1121,61 @@ func getBaseSwagger(t *testing.T) *openapi3.T {
},
}
}
func TestGetPathParamsAutoComplete(t *testing.T) {
testCases := map[string]struct {
schemaDefinition Definitions
path string
expected ParameterValue
}{
"no path params": {
schemaDefinition: Definitions{},
path: "/users",
expected: nil,
},
"with path params": {
schemaDefinition: Definitions{},
path: "/users/{userId}",
expected: ParameterValue{
"userId": {
Schema: &Schema{Value: ""},
},
},
},
"with multiple path params": {
schemaDefinition: Definitions{},
path: "/foo/{bar}.{taz}",
expected: ParameterValue{
"bar": {
Schema: &Schema{Value: ""},
},
"taz": {
Schema: &Schema{Value: ""},
},
},
},
"with nested multiple path params": {
schemaDefinition: Definitions{},
path: "/foo/{bar}.{taz}/{baz}/ok",
expected: ParameterValue{
"bar": {
Schema: &Schema{Value: ""},
},
"taz": {
Schema: &Schema{Value: ""},
},
"baz": {
Schema: &Schema{Value: ""},
},
},
},
}
for name, test := range testCases {
t.Run(name, func(t *testing.T) {
actual := getPathParamsAutoComplete(test.schemaDefinition, test.path)
require.Equal(t, test.expected, actual)
})
}
}

View File

@@ -57,6 +57,33 @@
}
}
}
},
"/files/{name}.{extension}": {
"get": {
"parameters": [
{
"in": "path",
"name": "extension",
"required": true,
"schema": {
"type": "string"
}
},
{
"in": "path",
"name": "name",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"default": {
"description": ""
}
}
}
}
}
}