Skip to content

Commit

Permalink
added support for automatically detecting path params
Browse files Browse the repository at this point in the history
  • Loading branch information
e-nikolov committed Jan 4, 2022
1 parent 0261631 commit b99e846
Show file tree
Hide file tree
Showing 12 changed files with 518 additions and 128 deletions.
105 changes: 104 additions & 1 deletion chi/openapi2.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ package chai

import (
"net/http"
"os"
"strings"

"github.com/davecgh/go-spew/spew"
"github.com/go-chai/chai/openapi2"
"github.com/go-chi/chi/v5"
"github.com/go-openapi/spec"
Expand All @@ -12,9 +15,11 @@ func OpenAPI2(r chi.Routes) (*spec.Swagger, error) {
routes := make([]*openapi2.Route, 0)

err := chi.Walk(r, func(method, route string, handler http.Handler, middlewares ...func(http.Handler) http.Handler) error {
params, newPath := getParams(route)
routes = append(routes, &openapi2.Route{
Method: method,
Path: route,
Path: newPath,
Params: params,
Handler: handler,
})

Expand All @@ -27,3 +32,101 @@ func OpenAPI2(r chi.Routes) (*spec.Swagger, error) {

return openapi2.Docs(routes)
}

func getParams(path string) ([]spec.Parameter, string) {
res := make([]spec.Parameter, 0)
newPath := ""

for {
param, before, rest := nextParam(path)
newPath += before

if param == nil {
break
}

newPath += "{" + param.Name + "}"

res = append(res, *param)
path = rest
}

if len(res) != 0 {
// openapi2.LogYAML(res)
}

return res, newPath
}

func nextParam(pattern string) (param *spec.Parameter, path string, rest string) {
path, rest, found := strings.Cut(pattern, "{")
if !found {
return nil, path, rest
}

// Read to closing } taking into account opens and closes in curl count (cc)
cc := 1
pe := 0

for i, c := range rest {
if c == '{' {
cc++
} else if c == '}' {
cc--

if cc == 0 {
pe = i
break
}
}
}
spew.Fdump(os.Stderr, rest[:pe])

key := rest[:pe]
pe++
rest = rest[pe:]

key, rexpat, _ := strings.Cut(key, ":")

if len(rexpat) > 0 {
if rexpat[0] != '^' {
rexpat = "^" + rexpat
}
if rexpat[len(rexpat)-1] != '$' {
rexpat += "$"
}
}

return &spec.Parameter{
CommonValidations: spec.CommonValidations{
Pattern: rexpat,
},
ParamProps: spec.ParamProps{
Name: key,
In: "path",
Required: true,
},
SimpleSchema: spec.SimpleSchema{
Type: "string",
},
}, path, rest
}

func getParams2(route string) []spec.Parameter {
res := make([]spec.Parameter, 0)

for _, sect := range strings.Split(route, "/") {
if strings.Contains(sect, "{") {
param := spec.Parameter{}
param.Name = strings.Trim(sect, "{}")
param.In = "path"
param.Required = true
param.Type = "string"
param.Pattern = "^[a-zA-Z0-9]+$"

res = append(res, param)
}
}

return res
}
2 changes: 1 addition & 1 deletion examples/chi/celler/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func main() {
chai.Get(r, "/{id}", c.ShowAccount)
chai.Get(r, "/", c.ListAccounts)
chai.Post(r, "/", c.AddAccount)
r.Delete("/{id}", c.DeleteAccount)
r.Delete("/{id:[0-9]+}", c.DeleteAccount)
r.Patch("/{id}", c.UpdateAccount)
r.Post("/{id}/images", c.UploadAccountImage)
})
Expand Down
69 changes: 34 additions & 35 deletions examples/docs/celler/docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -216,9 +216,8 @@ var doc = `{
"summary": "Delete an account",
"parameters": [
{
"type": "integer",
"format": "int64",
"description": "Account ID",
"pattern": "^[0-9]+$",
"type": "string",
"name": "id",
"in": "path",
"required": true
Expand Down Expand Up @@ -264,13 +263,6 @@ var doc = `{
],
"summary": "Update an account",
"parameters": [
{
"type": "integer",
"description": "Account ID",
"name": "id",
"in": "path",
"required": true
},
{
"description": "Update account",
"name": "account",
Expand All @@ -279,6 +271,13 @@ var doc = `{
"schema": {
"$ref": "#/definitions/model.UpdateAccount"
}
},
{
"type": "integer",
"description": "Account ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
Expand Down Expand Up @@ -323,19 +322,19 @@ var doc = `{
],
"summary": "Upload account image",
"parameters": [
{
"type": "integer",
"description": "Account ID",
"name": "id",
"in": "path",
"required": true
},
{
"type": "file",
"description": "account image",
"name": "file",
"in": "formData",
"required": true
},
{
"type": "integer",
"description": "Account ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
Expand Down Expand Up @@ -556,14 +555,10 @@ var doc = `{
"summary": "attribute example",
"parameters": [
{
"enum": [
"A",
"B",
"C"
],
"type": "string",
"description": "string enums",
"name": "enumstring",
"default": "A",
"description": "string default",
"name": "default",
"in": "query"
},
{
Expand All @@ -589,11 +584,14 @@ var doc = `{
"in": "query"
},
{
"maxLength": 10,
"minLength": 5,
"enum": [
"A",
"B",
"C"
],
"type": "string",
"description": "string valid",
"name": "string",
"description": "string enums",
"name": "enumstring",
"in": "query"
},
{
Expand All @@ -605,10 +603,11 @@ var doc = `{
"in": "query"
},
{
"maxLength": 10,
"minLength": 5,
"type": "string",
"default": "A",
"description": "string default",
"name": "default",
"description": "string valid",
"name": "string",
"in": "query"
}
],
Expand Down Expand Up @@ -746,15 +745,15 @@ var doc = `{
"parameters": [
{
"type": "integer",
"description": "Group ID",
"name": "group_id",
"description": "Account ID",
"name": "account_id",
"in": "path",
"required": true
},
{
"type": "integer",
"description": "Account ID",
"name": "account_id",
"description": "Group ID",
"name": "group_id",
"in": "path",
"required": true
}
Expand Down
Loading

0 comments on commit b99e846

Please sign in to comment.