getkin / kin-openapi

OpenAPI 3.0 (and Swagger v2) implementation for Go (parsing, converting, validation, and more)
MIT License
2.47k stars 411 forks source link

`nullable` not respected on `$ref` schemas #927

Open brandonbloom opened 3 months ago

brandonbloom commented 3 months ago
package openapi3

import (
    "testing"

    "github.com/stretchr/testify/require"
)

func TestIssueXXX(t *testing.T) {
    spec := `
openapi: 3.0.0
components:
  schemas:
    NullableString:
      type: string
      nullable: true
    NullableRef:
      $ref: "#/components/schemas/String"
      nullable: true
    String:
      type: string
`

    sl := NewLoader()
    doc, err := sl.LoadFromData([]byte(spec))
    require.NoError(t, err)

    require.False(t, doc.Components.Schemas["String"].Value.Nullable)
    require.True(t, doc.Components.Schemas["NullableString"].Value.Nullable)
    require.True(t, doc.Components.Schemas["NullableRef"].Value.Nullable) // this fails!
}
brandonbloom commented 3 months ago

More generally, it seems like this part of the spec is not respected (emphasis mine):

8.2.3.1. Direct References with "$ref"

The "$ref" keyword is an applicator that is used to reference a statically identified schema. Its results are the results of the referenced schema. Note that this definition of how the results are determined means that other keywords can appear alongside of "$ref" in the same schema object.

fenollp commented 3 months ago

openapi3.0 does not support the full JSON Schema spec. It is in openapi3.1 and this is still an open issue

brandonbloom commented 3 months ago

Apologies for the noise. I realized this after some more exploration/experimentation. I've got a workaround now:

export const refExtrasToAllOf = (schema: Schema): Schema => {
  if (RefSchema.guard(schema) && Object.keys(schema).length > 1) {
    const { $ref, ...extra } = schema;
    const allOf = AllOfSchema.guard(schema) ? schema.allOf : [];
    allOf.push({ $ref });
    return { ...extra, allOf };
  }
  return schema;
};