Skip to content

Commit

Permalink
Renamed OpenAPI parameter
Browse files Browse the repository at this point in the history
  • Loading branch information
EwenQuim committed Dec 12, 2024
1 parent c833e87 commit ce950ef
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 24 deletions.
40 changes: 20 additions & 20 deletions openapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,14 +189,14 @@ func validateSwaggerUrl(swaggerUrl string) bool {
}

// RegisterOpenAPIOperation registers an OpenAPI operation.
func RegisterOpenAPIOperation[T, B any](s *OpenAPI, route Route[T, B]) (*openapi3.Operation, error) {
func RegisterOpenAPIOperation[T, B any](openapi *OpenAPI, route Route[T, B]) (*openapi3.Operation, error) {
if route.Operation == nil {
route.Operation = openapi3.NewOperation()
}

// Request Body
if route.Operation.RequestBody == nil {
bodyTag := SchemaTagFromType(s, *new(B))
bodyTag := SchemaTagFromType(openapi, *new(B))

if bodyTag.Name != "unknown-interface" {
requestBody := newRequestBody[B](bodyTag, route.AcceptedContentTypes)
Expand All @@ -209,8 +209,8 @@ func RegisterOpenAPIOperation[T, B any](s *OpenAPI, route Route[T, B]) (*openapi
}

// Response - globals
for _, openAPIGlobalResponse := range s.globalOpenAPIResponses {
addResponseIfNotSet(s, route.Operation, openAPIGlobalResponse.Code, openAPIGlobalResponse.Description, openAPIGlobalResponse.ErrorType)
for _, openAPIGlobalResponse := range openapi.globalOpenAPIResponses {
addResponseIfNotSet(openapi, route.Operation, openAPIGlobalResponse.Code, openAPIGlobalResponse.Description, openAPIGlobalResponse.ErrorType)
}

// Automatically add non-declared 200 (or other) Response
Expand All @@ -227,7 +227,7 @@ func RegisterOpenAPIOperation[T, B any](s *OpenAPI, route Route[T, B]) (*openapi

// Automatically add non-declared Content for 200 (or other) Response
if responseDefault.Value.Content == nil {
responseSchema := SchemaTagFromType(s, *new(T))
responseSchema := SchemaTagFromType(openapi, *new(T))
content := openapi3.NewContentWithSchemaRef(&responseSchema.SchemaRef, []string{"application/json", "application/xml"})
responseDefault.Value.WithContent(content)
}
Expand All @@ -253,7 +253,7 @@ func RegisterOpenAPIOperation[T, B any](s *OpenAPI, route Route[T, B]) (*openapi
}
}

s.Description().AddOperation(route.Path, route.Method, route.Operation)
openapi.Description().AddOperation(route.Path, route.Method, route.Operation)

return route.Operation, nil
}
Expand All @@ -272,10 +272,10 @@ type SchemaTag struct {
Name string
}

func SchemaTagFromType(s *OpenAPI, v any) SchemaTag {
func SchemaTagFromType(openapi *OpenAPI, v any) SchemaTag {
if v == nil {
// ensure we add unknown-interface to our schemas
schema := s.getOrCreateSchema("unknown-interface", struct{}{})
schema := openapi.getOrCreateSchema("unknown-interface", struct{}{})
return SchemaTag{
Name: "unknown-interface",
SchemaRef: openapi3.SchemaRef{
Expand All @@ -285,7 +285,7 @@ func SchemaTagFromType(s *OpenAPI, v any) SchemaTag {
}
}

return dive(s, reflect.TypeOf(v), SchemaTag{}, 5)
return dive(openapi, reflect.TypeOf(v), SchemaTag{}, 5)
}

// dive returns a schemaTag which includes the generated openapi3.SchemaRef and
Expand All @@ -295,7 +295,7 @@ func SchemaTagFromType(s *OpenAPI, v any) SchemaTag {
// If the type is a slice or array type it will dive into the type as well as
// build and openapi3.Schema where Type is array and Ref is set to the proper
// components Schema
func dive(s *OpenAPI, t reflect.Type, tag SchemaTag, maxDepth int) SchemaTag {
func dive(openapi *OpenAPI, t reflect.Type, tag SchemaTag, maxDepth int) SchemaTag {
if maxDepth == 0 {
return SchemaTag{
Name: "default",
Expand All @@ -307,10 +307,10 @@ func dive(s *OpenAPI, t reflect.Type, tag SchemaTag, maxDepth int) SchemaTag {

switch t.Kind() {
case reflect.Ptr, reflect.Map, reflect.Chan, reflect.Func, reflect.UnsafePointer:
return dive(s, t.Elem(), tag, maxDepth-1)
return dive(openapi, t.Elem(), tag, maxDepth-1)

case reflect.Slice, reflect.Array:
item := dive(s, t.Elem(), tag, maxDepth-1)
item := dive(openapi, t.Elem(), tag, maxDepth-1)
tag.Name = item.Name
tag.Value = openapi3.NewArraySchema()
tag.Value.Items = &item.SchemaRef
Expand All @@ -319,29 +319,29 @@ func dive(s *OpenAPI, t reflect.Type, tag SchemaTag, maxDepth int) SchemaTag {
default:
tag.Name = t.Name()
if t.Kind() == reflect.Struct && strings.HasPrefix(tag.Name, "DataOrTemplate") {
return dive(s, t.Field(0).Type, tag, maxDepth-1)
return dive(openapi, t.Field(0).Type, tag, maxDepth-1)
}
tag.Ref = "#/components/schemas/" + tag.Name
tag.Value = s.getOrCreateSchema(tag.Name, reflect.New(t).Interface())
tag.Value = openapi.getOrCreateSchema(tag.Name, reflect.New(t).Interface())

return tag
}
}

// getOrCreateSchema is used to get a schema from the OpenAPI spec.
// If the schema does not exist, it will create a new schema and add it to the OpenAPI spec.
func (s *OpenAPI) getOrCreateSchema(key string, v any) *openapi3.Schema {
schemaRef, ok := s.Description().Components.Schemas[key]
func (openapi *OpenAPI) getOrCreateSchema(key string, v any) *openapi3.Schema {
schemaRef, ok := openapi.Description().Components.Schemas[key]
if !ok {
schemaRef = s.createSchema(key, v)
schemaRef = openapi.createSchema(key, v)
}
return schemaRef.Value
}

// createSchema is used to create a new schema and add it to the OpenAPI spec.
// Relies on the openapi3gen package to generate the schema, and adds custom struct tags.
func (s *OpenAPI) createSchema(key string, v any) *openapi3.SchemaRef {
schemaRef, err := s.Generator().NewSchemaRefForValue(v, s.Description().Components.Schemas)
func (openapi *OpenAPI) createSchema(key string, v any) *openapi3.SchemaRef {
schemaRef, err := openapi.Generator().NewSchemaRefForValue(v, openapi.Description().Components.Schemas)
if err != nil {
slog.Error("Error generating schema", "key", key, "error", err)
}
Expand All @@ -354,7 +354,7 @@ func (s *OpenAPI) createSchema(key string, v any) *openapi3.SchemaRef {

parseStructTags(reflect.TypeOf(v), schemaRef)

s.Description().Components.Schemas[key] = schemaRef
openapi.Description().Components.Schemas[key] = schemaRef

return schemaRef
}
Expand Down
6 changes: 3 additions & 3 deletions openapi_operations.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,13 @@ func (r Route[ResponseBody, RequestBody]) Param(paramType ParamType, name, descr
}

// Registers a response for the route, only if error for this code is not already set.
func addResponseIfNotSet(s *OpenAPI, operation *openapi3.Operation, code int, description string, errorType ...any) {
func addResponseIfNotSet(openapi *OpenAPI, operation *openapi3.Operation, code int, description string, errorType ...any) {
var responseSchema SchemaTag

if len(errorType) > 0 {
responseSchema = SchemaTagFromType(s, errorType[0])
responseSchema = SchemaTagFromType(openapi, errorType[0])
} else {
responseSchema = SchemaTagFromType(s, HTTPError{})
responseSchema = SchemaTagFromType(openapi, HTTPError{})
}
content := openapi3.NewContentWithSchemaRef(&responseSchema.SchemaRef, []string{"application/json"})

Expand Down
2 changes: 1 addition & 1 deletion option.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ func buildParam(name string, options ...func(*OpenAPIParam)) (OpenAPIParam, *ope
option(&param)
}

// Applies *OpenAPIParam to openapi3.Parameter
// Applies OpenAPIParam to openapi3.Parameter
// Why not use openapi3.NewHeaderParameter(name) directly?
// Because we might change the openapi3 library in the future,
// and we want to keep the flexibility to change the implementation without changing the API.
Expand Down

0 comments on commit ce950ef

Please sign in to comment.