This is my first foray into Swagger so please be gentle.
I have the following definitions:
definitions:
Payload:
type: object
properties:
indicators:
type: array
items:
$ref: '#/definitions/Indicator'
Indicator:
type: object
properties:
type:
type: string
computeOn:
type: array
items:
type: string
default:
- close
parameters:
type: object
BBANDS:
properties:
type:
type: string
default: BBANDS
computeOn:
type: array
items:
type: string
default:
- close
parameters:
type: object
properties:
timeperiod:
type: integer
format: int32
default: 5
nbdevup:
type: integer
format: int32
default: 2
nbdevdn:
type: integer
format: int32
default: 2
matype:
type: integer
format: int32
default: 0
DEMA:
properties:
type:
type: string
default: DEMA
computeOn:
type: array
items:
type: string
default:
- close
parameters:
type: object
properties:
timeperiod:
type: integer
format: int32
default: 5
So Payload
has a property called indicator
which is an array of Indicator
s. The BBANDS
and DEMA
are models which are of type Indicator
(which I know doesn't translate to Swagger). What I'd like to do is define an array of the actual models with their defaults, in this case BBANDS
and DEMA
. Something like this:
definitions:
Payload:
type: object
properties:
indicators:
type: array
items:
- '#/definitions/BBANDS'
- '#/definitions/DEMA'
or
definitions:
Payload:
type: object
properties:
indicators:
type: array
items:
- $ref '#/definitions/BBANDS'
- $ref '#/definitions/DEMA'
Neither of which work of course. The reason is while the Indicator
model describes an indicator
correctly, different indicator
s can have a different parameter set.
Is there a way to essentially define a list of several models or perhaps map the BBANDS
and DEMA
models into Indicator
?
Edit: Result of using @Helen's first suggestion in the Swagger Editor
Swagger/OpenAPI 2.0 does not support multiple types for items
, but there are a couple of ways to describe what you need.
Option 1 - Model Inheritance
As long as you have one field that is common between the models and can be used to distinguish between them, you can use model inheritance:
https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#schemaDiscriminator
https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#composition-and-inheritance-polymorphism
In your example, this property is type
(type="BBANDS"
or type="DEMA"
). So you can:
- Inherit the
BBANDS
and DEMA
models from Indicator
by using allOf
.
- Add
discriminator: type
to Indicator
to indicate that the type
property will be used to distinguish between the sub-models.
- Define
Payload
as an array of Indicator
. This way it can actually be an array of BBANDS
or an array of DEMA
.
definitions:
Payload:
type: object
properties:
indicators:
type: array
items:
$ref: '#/definitions/Indicator'
Indicator:
type: object
properties:
type:
type: string
# Limit the possible values if needed
#enum:
# - BBANDS
# - DEMA
computeOn:
type: array
items:
type: string
default:
- close
# The "type" property will be used to distinguish between the sub-models.
# The value of the "type" property MUST be the schema name, that is, "BBANDS" or "DEMA".
# (Or in other words, the sub-model schema names must match possible values of "type".)
discriminator: type
required:
- type
BBANDS:
allOf:
- $ref: '#/definitions/Indicator'
- type: object
properties:
parameters:
type: object
properties:
timeperiod:
type: integer
format: int32
default: 5
nbdevup:
type: integer
format: int32
default: 2
nbdevdn:
type: integer
format: int32
default: 2
matype:
type: integer
format: int32
default: 0
DEMA:
allOf:
- $ref: '#/definitions/Indicator'
- type: object
properties:
parameters:
type: object
properties:
timeperiod:
type: integer
format: int32
default: 5
Option 2 - Single Model
If all parameters
are integer, you can have a single model Indicator
with parameters
defined as a hashmap. But in this case you lose the ability to define the exact parameters
for specific indicator types.
definitions:
Indicator:
type: object
properties:
type:
type: string
enum:
- BBANDS
- DEMA
computeOn:
type: array
items:
type: string
default:
- close
parameters:
type: object
properties:
# This is a common parameter in both BBANDS and DEMA
timeperiod:
type: integer
format: int32
default: 5
# This will match additional parameters "nbdevup", "nbdevdn", "matype" in BBANDS
additionalProperties:
type: integer
AFAIK in array type can holds one type, if you want to have multiple types under an array, then need to define another super type and wrap the subtypes in it ( May be using object type ) like bellow. This restriction is because swagger-2.0 doesn't support all the features of json-schema.org, oneOf
, anyOf
, allOf
etc are some of it.
But you can make use the third party extension option available with swagger-2.0. Where you can name a Key with x-
, so that means you can include these oneOf
like x-oneOf
and when parsing the schema you do that using json-schema parser along with swagger schema parser.
One such example is given bellow,
Json-schema
{
"id": "http://some.site.somewhere/entry-schema#",
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "schema for an fstab entry",
"type": "object",
"required": [
"storage"
],
"properties": {
"storage": {
"type": "object",
"oneOf": [
{
"$ref": "#/definitions/diskDevice"
}
]
},
"deviceList": {
"type": "array",
"minItems": 1,
"items": {
"$ref": "#/definitions/Device"
}
}
},
"definitions": {
"diskDevice": {
"type": "object",
"properties": {
"label": {
"type": "string"
}
},
"required": [
"label"
]
},
"blockDevice": {
"type": "object",
"properties": {
"blockId": {
"type": "number"
}
},
"required": [
"blockId"
]
},
"CharDevice": {
"type": "object",
"properties": {
"charDeviceName": {
"type": "string"
}
},
"required": [
"charDeviceName"
]
},
"Device": {
"type": "object",
"oneOf": [
{
"$ref": "#/definitions/diskDevice"
},
{
"$ref": "#/definitions/blockDevice"
},
{
"$ref": "#/definitions/CharDevice"
}
]
}
}
}
Data or Payload
{
"storage": {"label": "adsf"},
"deviceList": [{"label": "asdf"}, {"blockId": 23}, {"charDeviceName": "asdf"}]
}
Use this site for play around with your sample data - http://www.jsonschemavalidator.net/
Note the deviceList
property and how it got constructed. Hope this helps you.