mmuurr
mmuurr

Reputation: 1580

`$ref`-ing multiple files at the #/components/schemas top-level in OpenAPI 3

In my API I have many many data structures (models), and it's helpful to keep them organized into separate files. For example, I have file widgets.a.yaml:

WidgetA1:
  # schema def
WidgetA2:
  # schema def

and another collection of defs in widgets.b.yaml:

WidgetB1:
  # schema def
WidgetB2:
  # schema def

Now in my main OpenAPI definition, if I do this:

# ...
# other OpenAPI def stuff
# ...
components:
  schemas:
    { $ref: widgets.a.yaml }

... the OpenAPI doc builds and generates some lovely documentation of type A widgets only.

If I try to reference both files like so:

# ...
# ther OpenAPI def stuff
# ...
components:
  schemas:
    { $ref: widgets.a.yaml }
    { $ref: widgets.b.yaml }

... the Swagger toolchain throws an error saying there's a duplicate key in schemas, but the two widgets.(a|b).yaml files are mutually-exclusive (i.e. no shared schema defs).

Does anyone have tips on organizing large data models into multiple files (each with potentially multiple JSON Schema schemas)?

And related, I'd really even prefer if there was some way to 'nest' models in #/components/schemas section of an OpenAPI doc ... e.g. referring to the widgets like #/components/schemas/widgets.a/WidgetA1. It appears, however, that the #/components/schemas section of OpenAPI docs is 'flat' (i.e. a flat namespace), and that all models must have a 'globally' unique key in that list ... is that true? I can find docs on various ways to organize pure JSON Schema projects, but wanting to use Swagger for documentation means needing to conform to OpenAPI, and there don't seem to be many established patterns for organizing large data models in those API specs. ("Large" here means hundreds of classes/models.)

Upvotes: 2

Views: 5408

Answers (1)

Helen
Helen

Reputation: 97590

In OpenAPI you can only reference individual schemas. This means you need to redefine the schema names in the components/schemas section and point each name to the corresponding schema definition:

components:
  schemas:
    WidgetA1:
      $ref: widgets.a.yaml#/WidgetA1
    WidgetA2:
      $ref: widgets.a.yaml#/WidgetA2
    WidgetB1:
      $ref: widgets.b.yaml#/WidgetB1
    ...

"Importing" the entire file directly under components/schemas is not supported, that is, the following is NOT valid:

components:
  schemas:
    $ref: widgets.a.yaml

all models must have a 'globally' unique key in that list ... is that true?

Yes.

I'd really even prefer if there was some way to 'nest' models in #/components/schemas section of an OpenAPI doc ... e.g. referring to the widgets like #/components/schemas/widgets.a/WidgetA1.

There's no concept of schema namespaces, but you can emulate them by using dots in schema names e.g. MyNamespace.WidgetA1.

components:
  schemas:
    MyNamespace1.WidgetA1:
      ...
    AnotherNamespace.WidgetB2:
      ...

Upvotes: 4

Related Questions