Skip to content

Commit

Permalink
initial request body traversal
Browse files Browse the repository at this point in the history
  • Loading branch information
jxsl13 committed Jul 23, 2023
1 parent 247ebb6 commit 62fe80f
Show file tree
Hide file tree
Showing 2 changed files with 139 additions and 0 deletions.
43 changes: 43 additions & 0 deletions traverse/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ func TestUniqueNames(t *testing.T) {
return nil
})
require.NoError(t, err)
t.Logf("total parameters: %d", count)

t.Logf("schemas: %s", k)
err = traverse.Schemas(doc, func(name string, schema *openapi3.SchemaRef) error {
Expand All @@ -55,8 +56,24 @@ func TestUniqueNames(t *testing.T) {
t.Logf("schema name = %s", name)
return nil
})
require.NoError(t, err)
t.Logf("total schemas: %d", count)

t.Logf("request bodies: %s", k)
err = traverse.RequestBodies(doc, func(name string, request *openapi3.RequestBodyRef) error {
require.NotRegexp(t, `^\d+`, name, "name starts with integer")
require.NotNil(t, request)
require.NotNil(t, request.Value)
require.Empty(t, request.Ref)
count++

assert.Falsef(t, names[name], "duplicate request bodies name: %s", name)
names[name] = true
t.Logf("request body name = %s", name)
return nil
})
require.NoError(t, err)
t.Logf("total request bodies: %d", count)
}

}
Expand All @@ -81,6 +98,7 @@ func TestTraverseParameters(t *testing.T) {
return nil
})
require.NoError(t, err)
t.Logf("total parameters: %d", count)
}

}
Expand All @@ -105,6 +123,31 @@ func TestTraverseSchemas(t *testing.T) {
return nil
})
require.NoError(t, err)
t.Logf("total schemas: %d", count)
}
}

func TestTraverseRequestBodies(t *testing.T) {

for k, doc := range Documents {
t.Logf("document: %s", k)
names := make(map[string]bool, 128)

count := 0
t.Logf("request bodies: %s", k)
err := traverse.RequestBodies(doc, func(name string, request *openapi3.RequestBodyRef) error {
require.NotRegexp(t, `^\d+`, name, "name starts with integer")
require.NotNil(t, request)
require.NotNil(t, request.Value)
require.Empty(t, request.Ref)
count++

assert.Falsef(t, names[name], "duplicate request bodies name: %s", name)
names[name] = true
t.Logf("request body name = %s", name)
return nil
})
require.NoError(t, err)
t.Logf("total request bodies: %d", count)
}
}
96 changes: 96 additions & 0 deletions traverse/request_bodies.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package traverse

import (
"net/http"

"github.com/getkin/kin-openapi/openapi3"
)

var RequestBodyNameSuffix = "Request"

// Parameters traverses #/components/parameters
// and individual inline defined parameters
func RequestBodies(doc *openapi3.T, visitor RequestBodyRefVisitor) error {

var err error

if doc.Components != nil {
for k, v := range doc.Components.RequestBodies {
if v.Ref != "" {
continue
}
if v.Value == nil {
continue
}
err = visitor(k, v)
if err != nil {
return err
}
}
}

for k, v := range doc.Paths {
if v.Ref != "" {
// assumption: seemingly it is possible to reference complete path implementations
// we only want to iterate over local definitions. Global schemas should be handled elsewhere.
// TODO: check if path references can be defined globally
continue
}

err = OperationRequestBodyRefs(http.MethodGet, k, v.Get, visitor)
if err != nil {
return err
}
err = OperationRequestBodyRefs(http.MethodHead, k, v.Head, visitor)
if err != nil {
return err
}
err = OperationRequestBodyRefs(http.MethodOptions, k, v.Options, visitor)
if err != nil {
return err
}
err = OperationRequestBodyRefs(http.MethodPatch, k, v.Patch, visitor)
if err != nil {
return err
}
err = OperationRequestBodyRefs(http.MethodPost, k, v.Post, visitor)
if err != nil {
return err
}
err = OperationRequestBodyRefs(http.MethodPut, k, v.Put, visitor)
if err != nil {
return err
}
err = OperationRequestBodyRefs(http.MethodTrace, k, v.Trace, visitor)
if err != nil {
return err
}

}

return nil
}

func OperationRequestBodyRefs(method, path string, operation *openapi3.Operation, visitor RequestBodyRefVisitor) error {
if operation == nil {
return nil
}

var err error
if operation.RequestBody == nil {
return nil
} else if operation.RequestBody.Ref != "" {
// skip references
return nil
}

name := NameFromOperation(method, path, operation, RequestBodyNameSuffix)
err = visitor(name, operation.RequestBody)
if err != nil {
return err
}

return nil
}

type RequestBodyRefVisitor func(name string, request *openapi3.RequestBodyRef) error

0 comments on commit 62fe80f

Please sign in to comment.