Skip to content

Commit

Permalink
improve oas3
Browse files Browse the repository at this point in the history
  • Loading branch information
hgiasac committed Dec 24, 2024
1 parent 3f8f362 commit 5fe0cf2
Show file tree
Hide file tree
Showing 16 changed files with 1,249 additions and 421 deletions.
8 changes: 4 additions & 4 deletions ndc-http-schema/openapi/internal/oas2.go
Original file line number Diff line number Diff line change
Expand Up @@ -251,14 +251,14 @@ func (oc *OAS2Builder) convertComponentSchemas(schemaItem orderedmap.Pair[string
scalar.Representation = schema.NewTypeRepresentationJSON().Encode()
oc.schema.ScalarTypes[refName] = *scalar
oc.schemaCache[cacheKey] = SchemaInfoCache{
Name: refName,
Schema: schema.NewNamedType(refName),
TypeRead: schema.NewNamedType(refName),
TypeWrite: schema.NewNamedType(refName),
TypeSchema: schemaResult,
}
} else {
oc.schemaCache[cacheKey] = SchemaInfoCache{
Name: typeName,
Schema: typeEncoder,
TypeRead: typeEncoder,
TypeWrite: typeEncoder,
TypeSchema: schemaResult,
}
}
Expand Down
13 changes: 8 additions & 5 deletions ndc-http-schema/openapi/internal/oas2_schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,10 @@ func (oc *oas2SchemaBuilder) getSchemaTypeFromProxy(schemaProxy *base.SchemaProx
return nil, nil, err
}
} else if typeCache, ok := oc.builder.schemaCache[rawRefName]; ok {
ndcType = typeCache.Schema
ndcType = typeCache.TypeRead
if oc.writeMode {
ndcType = typeCache.TypeWrite
}
typeSchema = createSchemaFromOpenAPISchema(innerSchema)
if typeCache.TypeSchema != nil {
typeSchema.Type = typeCache.TypeSchema.Type
Expand All @@ -292,8 +295,8 @@ func (oc *oas2SchemaBuilder) getSchemaTypeFromProxy(schemaProxy *base.SchemaProx
refName := getSchemaRefTypeNameV2(rawRefName)
schemaName := utils.ToPascalCase(refName)
oc.builder.schemaCache[rawRefName] = SchemaInfoCache{
Name: schemaName,
Schema: schema.NewNamedType(schemaName),
TypeRead: schema.NewNamedType(schemaName),
TypeWrite: schema.NewNamedType(schemaName),
}

_, ok := oc.builder.schema.ObjectTypes[schemaName]
Expand All @@ -303,8 +306,8 @@ func (oc *oas2SchemaBuilder) getSchemaTypeFromProxy(schemaProxy *base.SchemaProx
return nil, nil, err
}
oc.builder.schemaCache[rawRefName] = SchemaInfoCache{
Name: schemaName,
Schema: ndcType,
TypeRead: ndcType,
TypeWrite: ndcType,
TypeSchema: typeSchema,
}
} else {
Expand Down
47 changes: 25 additions & 22 deletions ndc-http-schema/openapi/internal/oas3.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package internal

import (
"fmt"
"log"
"log/slog"
"strings"

Expand All @@ -23,14 +24,14 @@ type OAS3Builder struct {
// stores prebuilt and evaluating information of component schema types.
// some undefined schema types aren't stored in either object nor scalar,
// or self-reference types that haven't added into the object_types map yet.
// This cache temporarily stores them to avoid infinite recursive reference.
// This cache temporarily stores them to avoid infinite recursive references.
schemaCache map[string]SchemaInfoCache
}

// SchemaInfoCache stores prebuilt information of component schema types.
type SchemaInfoCache struct {
Name string
Schema schema.TypeEncoder
TypeRead schema.TypeEncoder
TypeWrite schema.TypeEncoder
TypeSchema *rest.TypeSchema
}

Expand Down Expand Up @@ -266,23 +267,29 @@ func (oc *OAS3Builder) convertComponentSchemas(schemaItem orderedmap.Pair[string
return nil
}

typeEncoder, schemaResult, err := newOAS3SchemaBuilder(oc, "", rest.InBody, false).
schemaResult, err := newOAS3SchemaBuilder(oc, "", rest.InBody, false).
getSchemaType(typeSchema, []string{typeKey})
if err != nil {
return err
}

if schemaResult == nil {
log.Println("can not build schema for", typeKey)

return nil
}

var typeName string
if typeEncoder != nil {
typeName = getNamedType(typeEncoder, true, "")
if schemaResult.TypeRead != nil {
typeName = getNamedType(schemaResult.TypeRead, true, "")
}

if schemaResult != nil {
if schemaResult.XML == nil {
schemaResult.XML = &rest.XMLSchema{}
if schemaResult.TypeSchema != nil {
if schemaResult.TypeSchema.XML == nil {
schemaResult.TypeSchema.XML = &rest.XMLSchema{}
}
if schemaResult.XML.Name == "" {
schemaResult.XML.Name = typeKey
if schemaResult.TypeSchema.XML.Name == "" {
schemaResult.TypeSchema.XML.Name = typeKey
}
}

Expand All @@ -295,22 +302,18 @@ func (oc *OAS3Builder) convertComponentSchemas(schemaItem orderedmap.Pair[string

cacheKey := "#/components/schemas/" + typeKey
// treat no-property objects as a Arbitrary JSON scalar
if typeEncoder == nil || typeName == string(rest.ScalarJSON) {
if schemaResult.TypeRead == nil || typeName == string(rest.ScalarJSON) {
refName := utils.ToPascalCase(typeKey)
scalar := schema.NewScalarType()
scalar.Representation = schema.NewTypeRepresentationJSON().Encode()
oc.schema.ScalarTypes[refName] = *scalar
oc.schemaCache[cacheKey] = SchemaInfoCache{
Name: refName,
Schema: schema.NewNamedType(refName),
TypeSchema: schemaResult,
TypeRead: schema.NewNamedType(refName),
TypeWrite: schema.NewNamedType(refName),
TypeSchema: schemaResult.TypeSchema,
}
} else {
oc.schemaCache[cacheKey] = SchemaInfoCache{
Name: typeName,
Schema: typeEncoder,
TypeSchema: schemaResult,
}
oc.schemaCache[cacheKey] = *schemaResult
}

return err
Expand Down Expand Up @@ -369,8 +372,8 @@ func (oc *OAS3Builder) populateWriteSchemaType(schemaType schema.Type) (schema.T
_, evaluated := oc.schemaCache[ty.Name]
if !evaluated {
oc.schemaCache[ty.Name] = SchemaInfoCache{
Name: ty.Name,
Schema: schema.NewNamedType(ty.Name),
TypeRead: schema.NewNamedType(ty.Name),
TypeWrite: schema.NewNamedType(ty.Name),
TypeSchema: &rest.TypeSchema{
Type: []string{"object"},
},
Expand Down
26 changes: 13 additions & 13 deletions ndc-http-schema/openapi/internal/oas3_operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ func (oc *oas3OperationBuilder) convertParameters(params []*v3.Parameter, apiPat
if param.Required != nil && *param.Required {
paramRequired = true
}
schemaType, apiSchema, err := newOAS3SchemaBuilder(oc.builder, apiPath, rest.ParameterLocation(param.In), true).
schemaResult, err := newOAS3SchemaBuilder(oc.builder, apiPath, rest.ParameterLocation(param.In), true).
getSchemaTypeFromProxy(param.Schema, !paramRequired, append(fieldPaths, paramName))
if err != nil {
return err
Expand All @@ -207,12 +207,12 @@ func (oc *oas3OperationBuilder) convertParameters(params []*v3.Parameter, apiPat

argument := rest.ArgumentInfo{
ArgumentInfo: schema.ArgumentInfo{
Type: schemaType.Encode(),
Type: schemaResult.TypeWrite.Encode(),
},
HTTP: &rest.RequestParameter{
Name: paramName,
In: paramLocation,
Schema: apiSchema,
Schema: schemaResult.TypeSchema,
EncodingObject: encoding,
},
}
Expand Down Expand Up @@ -263,13 +263,13 @@ func (oc *oas3OperationBuilder) convertRequestBody(reqBody *v3.RequestBody, apiP
if contentType == rest.ContentTypeFormURLEncoded {
location = rest.InQuery
}
schemaType, typeSchema, err := newOAS3SchemaBuilder(oc.builder, apiPath, location, true).
typeResult, err := newOAS3SchemaBuilder(oc.builder, apiPath, location, true).
getSchemaTypeFromProxy(content.Schema, !bodyRequired, fieldPaths)
if err != nil {
return nil, nil, err
}

if typeSchema == nil {
if typeResult == nil || typeResult.TypeRead == nil {
return nil, nil, nil
}

Expand All @@ -278,7 +278,7 @@ func (oc *oas3OperationBuilder) convertRequestBody(reqBody *v3.RequestBody, apiP
}

if content.Encoding == nil || content.Encoding.Len() == 0 {
return bodyResult, schemaType, nil
return bodyResult, typeResult.TypeWrite, nil
}

bodyResult.Encoding = make(map[string]rest.EncodingObject)
Expand Down Expand Up @@ -311,7 +311,7 @@ func (oc *oas3OperationBuilder) convertRequestBody(reqBody *v3.RequestBody, apiP
continue
}

ndcType, typeSchema, err := newOAS3SchemaBuilder(oc.builder, apiPath, rest.InHeader, true).
typeResult, err := newOAS3SchemaBuilder(oc.builder, apiPath, rest.InHeader, true).
getSchemaTypeFromProxy(header.Schema, header.AllowEmptyValue, append(fieldPaths, key))
if err != nil {
return nil, nil, err
Expand All @@ -333,12 +333,12 @@ func (oc *oas3OperationBuilder) convertRequestBody(reqBody *v3.RequestBody, apiP
argumentName := encodeHeaderArgumentName(key)
headerParam := rest.RequestParameter{
ArgumentName: argumentName,
Schema: typeSchema,
Schema: typeResult.TypeSchema,
EncodingObject: headerEncoding,
}

argument := schema.ArgumentInfo{
Type: ndcType.Encode(),
Type: typeResult.TypeWrite.Encode(),
}
headerDesc := utils.StripHTMLTags(header.Description)
if headerDesc != "" {
Expand All @@ -354,7 +354,7 @@ func (oc *oas3OperationBuilder) convertRequestBody(reqBody *v3.RequestBody, apiP
bodyResult.Encoding[iter.Key()] = item
}

return bodyResult, schemaType, nil
return bodyResult, typeResult.TypeWrite, nil
}

func (oc *oas3OperationBuilder) convertResponse(responses *v3.Responses, apiPath string, fieldPaths []string) (schema.TypeEncoder, *rest.Response, error) {
Expand Down Expand Up @@ -428,7 +428,7 @@ func (oc *oas3OperationBuilder) convertResponse(responses *v3.Responses, apiPath
return getResultTypeFromContentType(oc.builder.schema, contentType), schemaResponse, nil
}

schemaType, _, err := newOAS3SchemaBuilder(oc.builder, apiPath, rest.InBody, false).
typeResult, err := newOAS3SchemaBuilder(oc.builder, apiPath, rest.InBody, false).
getSchemaTypeFromProxy(bodyContent.Schema, false, fieldPaths)
if err != nil {
return nil, nil, err
Expand All @@ -438,9 +438,9 @@ func (oc *oas3OperationBuilder) convertResponse(responses *v3.Responses, apiPath
case rest.ContentTypeNdJSON:
// Newline Delimited JSON (ndjson) format represents a stream of structured objects
// so the response would be wrapped with an array
return schema.NewArrayType(schemaType), schemaResponse, nil
return schema.NewArrayType(typeResult.TypeRead), schemaResponse, nil
default:
return schemaType, schemaResponse, nil
return typeResult.TypeRead, schemaResponse, nil
}
}

Expand Down
Loading

0 comments on commit 5fe0cf2

Please sign in to comment.