Define an array of multiple models in Swagger 2.0

This is my first Swagger raid, so please be careful.

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 an indicator property, which is an indicator s array. BBANDS and DEMA are models that are of type indicator (which, as I know, is not translated into Swagger). What I would like to do is define an array of real models with their default values, in this case BBANDS and DEMA . Something like that:

 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' 

None of them work, of course. The reason is that the indicator model describes the indicator correctly, another indicator may have a different set of parameters.

Is there a way to substantially define a list of several models, or perhaps display BBANDS and DEMA models in indicator ?

Edit: Result of using @Helen's first sentence in Swagger Editor

enter image description here

+5
source share
2 answers

Swagger / OpenAPI 2.0 does not support multiple types for items , but there are several ways to describe what you need.

Option 1 - Model Inheritance

As long as you have one field that is common to models, and can be used to distinguish 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 is the type property ( type="BBANDS" or type="DEMA" ). So you can:

  • Inherit the BBANDS and DEMA models with allOf .
  • Add discriminator: type to Indicator to indicate that the type property will be used to distinguish between submodels.
  • Define Payload as an Indicator array. Thus, it can actually be a BBANDS array or a DEMA array.

 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 one Indicator model with parameters , defined as a hash map. But in this case, you lose the ability to determine the exact parameters for certain types of indicators.

 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 
+4
source

AFAIK in an array type can contain one type, if you want to have several types under the array, then you need to define another super-type and wrap the subtypes in it (maybe use an object type), as shown below. This limitation is due to the fact that swagger-2.0 does not support all the functions of json-schema.org, oneOf , anyOf , allOf , etc. Some of them.

But you can use a third-party extension available with swagger-2.0. If you can name the key with x- , then you can include these oneOf as x-oneOf when analyzing the circuit you are doing, using the json-schema parser along with the smagger parser.

One such example is given below,

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 to play with your sample data - http://www.jsonschemavalidator.net/

Pay attention to the deviceList property and how to create it. Hope this helps you.

0
source

Source: https://habr.com/ru/post/1261122/


All Articles