I am trying to define an API in Swagger where the result of a GET is an array of items for model MainModel each with an associated array of items from another model called AnotherModel. Something like this (which does not seem to be allowed):
responses:
200:
description: search results matching criteria
schema:
type: array
items:
$ref: '#/definitions/MainModel'
type: array
items: $ref: '#/definitions/AnotherModel'
First of all, OpenAPI Specification supports associative arrays / dictionaries with string keys only, such as:
{
"foo": 5,
"bar": 2
}
but not C#'s Dictionary<int, string>
where keys are int
.
An associative array is defined by using an object
schema with the additionalProperties
keyword specifying the type of array values. The key type is not mentioned because keys are always strings.
type: object
additionalProperties:
type: <type of array values>
# OR
# $ref: '#/definitions/ValueModel'
Similarly, an array of associative arrays can be defined as follows:
type: array
items:
type: object
additionalProperties:
type: <type of values in associative array>
# OR
# $ref: '#/definitions/ValueModel'
In your example, the values of associative array are of type AnotherModel
. So an inline definition would look like:
responses:
200:
description: search results matching criteria
schema:
type: array
items:
type: object
additionalProperties:
$ref: '#/definitions/AnotherModel'
definitions:
AnotherModel:
type: <whatever> # TODO
Or if we introduce an intermediate MainModel
that represents the associative array (as in your original example):
responses:
200:
description: search results matching criteria
schema:
type: array
items:
$ref: '#/definitions/MainModel'
definitions:
MainModel: # Associative array of AnotherModel
type: object
additionalProperties:
$ref: '#/definitions/AnotherModel'
AnotherModel:
type: <whatever> # TODO
A couple of notes:
Each model referenced via $ref
must be defined in the definitions
section. So if you use $ref: '#/definitions/MainModel'
, your spec must include
definitions:
MainModel:
$ref
works by replacing itself and all its sibling elements with the definition it is pointing at. That's why your original example is not valid:
items:
$ref: '#/definitions/MainModel'
type: array
items: $ref: '#/definitions/AnotherModel'
Nested models can be either defined completely inline or referenced via $ref
, but not both.