@@ -9,16 +9,13 @@ import (
99 "github.com/aep-dev/aepcli/internal/utils"
1010)
1111
12- const contentType = "application/json"
13-
1412type ServiceDefinition struct {
1513 ServerURL string
1614 Resources map [string ]* Resource
1715}
1816
1917func GetServiceDefinition (api * openapi.OpenAPI , serverURL , pathPrefix string ) (* ServiceDefinition , error ) {
2018 slog .Debug ("parsing openapi" , "pathPrefix" , pathPrefix )
21- oasVersion := api .Info .Version
2219 resourceBySingular := make (map [string ]* Resource )
2320 // we try to parse the paths to find possible resources, since
2421 // they may not always be annotated as such.
@@ -40,13 +37,13 @@ func GetServiceDefinition(api *openapi.OpenAPI, serverURL, pathPrefix string) (*
4037 }
4138 if pathItem .Get != nil {
4239 if resp , ok := pathItem .Get .Responses ["200" ]; ok {
43- sRef = getSchemaFromResponse (resp , oasVersion )
40+ sRef = api . GetSchemaFromResponse (resp )
4441 r .GetMethod = & GetMethod {}
4542 }
4643 }
4744 if pathItem .Patch != nil {
4845 if resp , ok := pathItem .Patch .Responses ["200" ]; ok {
49- sRef = getSchemaFromResponse (resp , oasVersion )
46+ sRef = api . GetSchemaFromResponse (resp )
5047 r .UpdateMethod = & UpdateMethod {}
5148 }
5249 }
@@ -55,7 +52,7 @@ func GetServiceDefinition(api *openapi.OpenAPI, serverURL, pathPrefix string) (*
5552 if pathItem .Post != nil {
5653 // check if there is a query parameter "id"
5754 if resp , ok := pathItem .Post .Responses ["200" ]; ok {
58- sRef = getSchemaFromResponse (resp , oasVersion )
55+ sRef = api . GetSchemaFromResponse (resp )
5956 supportsUserSettableCreate := false
6057 for _ , param := range pathItem .Post .Parameters {
6158 if param .Name == "id" {
@@ -69,23 +66,26 @@ func GetServiceDefinition(api *openapi.OpenAPI, serverURL, pathPrefix string) (*
6966 // list method
7067 if pathItem .Get != nil {
7168 if resp , ok := pathItem .Get .Responses ["200" ]; ok {
72- ct := resp .Content [contentType ]
73- respSchema := getSchemaFromResponse (resp , oasVersion )
74- resolvedSchema , err := dereferencedSchema (* respSchema , api )
75- if err != nil {
76- return nil , fmt .Errorf ("error dereferencing schema %q: %v" , ct .Schema .Ref , err )
77- }
78- found := false
79- for _ , property := range resolvedSchema .Properties {
80- if property .Type == "array" {
81- sRef = property .Items
82- r .ListMethod = & ListMethod {}
83- found = true
84- break
69+ respSchema := api .GetSchemaFromResponse (resp )
70+ if respSchema == nil {
71+ slog .Warn (fmt .Sprintf ("resource %q has a LIST method with a response schema, but the response schema is nil." , path ))
72+ } else {
73+ resolvedSchema , err := api .DereferenceSchema (* respSchema )
74+ if err != nil {
75+ return nil , fmt .Errorf ("error dereferencing schema %q: %v" , respSchema .Ref , err )
76+ }
77+ found := false
78+ for _ , property := range resolvedSchema .Properties {
79+ if property .Type == "array" {
80+ sRef = property .Items
81+ r .ListMethod = & ListMethod {}
82+ found = true
83+ break
84+ }
85+ }
86+ if ! found {
87+ slog .Warn (fmt .Sprintf ("resource %q has a LIST method with a response schema, but the items field is not present or is not an array." , path ))
8588 }
86- }
87- if ! found {
88- slog .Warn (fmt .Sprintf ("resource %q has a LIST method with a response schema, but the items field is not present or is not an array." , path ))
8989 }
9090 }
9191 }
@@ -94,17 +94,17 @@ func GetServiceDefinition(api *openapi.OpenAPI, serverURL, pathPrefix string) (*
9494 // s should always be a reference to a schema in the components section.
9595 parts := strings .Split (sRef .Ref , "/" )
9696 key := parts [len (parts )- 1 ]
97- schema , ok := api .Components . Schemas [ key ]
98- if ! ok {
99- return nil , fmt .Errorf ("schema %q not found " , key )
97+ dereferencedSchema , err := api .DereferenceSchema ( * sRef )
98+ if err != nil {
99+ return nil , fmt .Errorf ("error dereferencing schema %q: %v " , sRef . Ref , err )
100100 }
101101 singular := utils .PascalCaseToKebabCase (key )
102102 pattern := strings .Split (path , "/" )[1 :]
103103 // collection-level patterns don't include the singular, so we need to add it
104104 if ! p .IsResourcePattern {
105105 pattern = append (pattern , fmt .Sprintf ("{%s}" , singular ))
106106 }
107- r2 , err := getOrPopulateResource (singular , pattern , & schema , resourceBySingular , api )
107+ r2 , err := getOrPopulateResource (singular , pattern , dereferencedSchema , resourceBySingular , api )
108108 if err != nil {
109109 return nil , fmt .Errorf ("error populating resource %q: %v" , r .Singular , err )
110110 }
@@ -224,26 +224,3 @@ func foldResourceMethods(from, into *Resource) {
224224 into .DeleteMethod = from .DeleteMethod
225225 }
226226}
227-
228- func dereferencedSchema (schema openapi.Schema , api * openapi.OpenAPI ) (* openapi.Schema , error ) {
229- if schema .Ref != "" {
230- parts := strings .Split (schema .Ref , "/" )
231- key := parts [len (parts )- 1 ]
232- childSchema , ok := api .Components .Schemas [key ]
233- if ! ok {
234- return nil , fmt .Errorf ("schema %q not found" , key )
235- }
236- return dereferencedSchema (childSchema , api )
237- }
238- return & schema , nil
239- }
240-
241- func getSchemaFromResponse (r openapi.Response , oasVersion string ) * openapi.Schema {
242- switch oasVersion {
243- case "2.0" :
244- return r .Schema
245- default :
246- ct := r .Content [contentType ]
247- return ct .Schema
248- }
249- }
0 commit comments