Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions build-map-keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,7 @@ const (
keyFlows = "flows"
keyAuthorizationURL = "authorizationUrl"
keyScopes = "scopes"
keyParameters = "parameters"
keyRequired = "required"
keySchema = "schema"
)
41 changes: 41 additions & 0 deletions build.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ func makeAllPathsMap(paths *Paths) pathsMap {
pathMap[keySecurity] = makeSecurityMap(&path.Security)
pathMap[keyRequestBody] = makeRequestBodyMap(&path.RequestBody)
pathMap[keyResponses] = makeResponsesMap(&path.Responses)
pathMap[keyParameters] = makeParametersMap(path.Parameters)

allPaths[path.Route][strings.ToLower(path.HTTPMethod)] = pathMap
}
Expand Down Expand Up @@ -346,3 +347,43 @@ const emptyStr = ""
func isStrEmpty(s string) bool {
return s == emptyStr
}

func makeParametersMap(parameters Parameters) []map[string]interface{} {
parametersMap := []map[string]interface{}{}

for i := 0; i < len(parameters); i++ {
var (
param = &parameters[i]
paramMap = make(map[string]interface{})
)

paramMap[keyName] = param.Name
paramMap[keyIn] = param.In
paramMap[keyDescription] = param.Description
paramMap[keyRequired] = param.Required
paramMap[keySchema] = makeSchemaMap(&param.Schema)

parametersMap = append(parametersMap, paramMap)
}

return parametersMap
}

func makeSchemaMap(schema *Schema) map[string]interface{} {
schemaMap := make(map[string]interface{})

if !isStrEmpty(schema.Ref) {
schemaMap[keyRef] = schema.Ref
} else {
schemaMap[keyName] = schema.Name
schemaMap[keyType] = schema.Type
if len(schema.Properties) > 0 {
schemaMap[keyProperties] = makePropertiesMap(&schema.Properties)
}
if schema.XML.Name != "" {
schemaMap[keyXML] = map[string]interface{}{"name": schema.XML.Name}
}
}

return schemaMap
}
113 changes: 113 additions & 0 deletions build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package docs

import (
"bytes"
"reflect"
"testing"
)

Expand Down Expand Up @@ -229,3 +230,115 @@ func TestOAS_BuildStream(t *testing.T) {
})
}
}

func Test_makeParametersMap(t *testing.T) {
t.Parallel()

type args struct {
parameters Parameters
}

tests := []struct {
name string
args args
want []map[string]interface{}
}{
{
name: "success-minimal",
args: args{
parameters: Parameters{{
Name: "id",
In: "path",
Description: "test",
Required: true,
Schema: Schema{Name: "id", Type: "integer"},
}},
},
want: []map[string]interface{}{{
"name": "id",
"in": "path",
"description": "test",
"required": true,
"schema": map[string]interface{}{"name": "id", "type": "integer"},
}},
},
{
name: "success-full",
args: args{
parameters: Parameters{{
Name: "id",
In: "path",
Description: "test",
Required: true,
Schema: Schema{
Name: "id",
Type: "integer",
Properties: SchemaProperties{{Name: "id", Type: "integer"}},
},
}},
},
want: []map[string]interface{}{{
"name": "id",
"in": "path",
"description": "test",
"required": true,
"schema": map[string]interface{}{
"name": "id",
"type": "integer",
"properties": map[string]interface{}{
"id": map[string]interface{}{"type": "integer"},
},
},
}},
},
{
name: "success-ref",
args: args{
parameters: Parameters{{
Name: "id",
In: "path",
Description: "test",
Required: true,
Schema: Schema{Ref: "$some-ref"},
}},
},
want: []map[string]interface{}{{
"name": "id",
"in": "path",
"description": "test",
"required": true,
"schema": map[string]interface{}{"$ref": "$some-ref"},
}},
},
{
name: "success-xml-entry",
args: args{
parameters: Parameters{{
Name: "id",
In: "path",
Description: "test",
Required: true,
Schema: Schema{Name: "id", Type: "integer", XML: XMLEntry{Name: "id"}},
}},
},
want: []map[string]interface{}{{
"name": "id",
"in": "path",
"description": "test",
"required": true,
"schema": map[string]interface{}{"name": "id", "type": "integer", "xml": map[string]interface{}{"name": "id"}},
}},
},
}
for _, tt := range tests {
trn := tt

t.Run(trn.name, func(t *testing.T) {
t.Parallel()

if got := makeParametersMap(trn.args.parameters); !reflect.DeepEqual(got, trn.want) {
t.Errorf("makeParametersMap() = %+v, want %+v", got, trn.want)
}
})
}
}
28 changes: 28 additions & 0 deletions examples/stream_output/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,24 @@ func main() {
Route: "/users",
HTTPMethod: "GET",
OperationID: "getUser",
Summary: "Get Users list",
Responses: docs.Responses{
getResponseOK(),
},
// HandlerFuncName: "handleCreateUser",
RequestBody: docs.RequestBody{
Description: "Get Users list",
Content: docs.ContentTypes{
getContentApplicationJSON("#/components/schemas/User"),
},
Required: true,
},
})

apiDoc.AddRoute(&docs.Path{
Route: "/users/{id}",
HTTPMethod: "GET",
OperationID: "getUser",
Summary: "Get a User",
Responses: docs.Responses{
getResponseOK(),
Expand All @@ -59,6 +77,16 @@ func main() {
},
Required: true,
},
Parameters: docs.Parameters{{
Name: "id",
Description: "User ID",
In: "path",
Required: true,
Schema: docs.Schema{
Name: "id",
Type: "string",
},
}},
})

mux := http.NewServeMux()
Expand Down
20 changes: 20 additions & 0 deletions models.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ type Path struct {
RequestBody RequestBody `yaml:"requestBody"`
Responses Responses `yaml:"responses"`
Security SecurityEntities `yaml:"security,omitempty"`
Parameters Parameters `yaml:"parameters,omitempty"`
HandlerFuncName string `yaml:"-"`
}

Expand Down Expand Up @@ -210,6 +211,25 @@ type SecurityScope struct {
Description string `yaml:"description,omitempty"`
}

// Parameters is a slice of Parameter objects.
type Parameters []Parameter

// Parameter represents OAS parameter object.
type Parameter struct {
// If in is "path", the name field MUST correspond to a template expression occurring within
// the path field in the Paths Object. See Path Templating for further information.
// If in is "header" and the name field is "Accept", "Content-Type" or "Authorization",
// the parameter definition SHALL be ignored.
// For all other cases, the name corresponds to the parameter name used by the in property.
Name string `yaml:"name,omitempty"`
In string `yaml:"in,omitempty"` // "query", "header", "path" or "cookie".
Description string `yaml:"description,omitempty"`
Required bool `yaml:"required,omitempty"`
Deprecated bool `yaml:"deprecated,omitempty"`
AllowEmptyValue bool `yaml:"allowEmptyValue,omitempty"`
Schema Schema
}

// isEmpty checks if *ExternalDocs struct is empty.
func (ed *ExternalDocs) isEmpty() bool {
if ed == nil {
Expand Down