在Swagger 2.0中定义多个模型的数组

时间:2016-12-12 07:39:20

标签: swagger swagger-2.0

这是我第一次涉足Swagger,所以请保持温和。

我有以下定义:

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

因此Payload有一个名为indicator的属性,它是Indicator的数组。 BBANDSDEMA type Indicator的模型(我知道它不会转换为Swagger)。我想要做的是定义一个具有默认值的实际模型数组,在本例中为BBANDSDEMA。像这样:

definitions:
  Payload:
    type: object
    properties:
      indicators:
        type: array
        items:
          - '#/definitions/BBANDS'
          - '#/definitions/DEMA'

definitions:
  Payload:
    type: object
    properties:
      indicators:
        type: array
        items:
          - $ref '#/definitions/BBANDS'
          - $ref '#/definitions/DEMA'

当然,这两项工作都没有。原因是Indicator模型正确描述了indicator,而不同的indicator s可以有不同的参数集。

有没有办法基本上定义几个模型的列表,或者可能将BBANDSDEMA模型映射到Indicator

编辑:在Swagger编辑器中使用@ Helen的第一个建议的结果

enter image description here

2 个答案:

答案 0 :(得分:8)

Swagger / OpenAPI 2.0不支持items的多种类型,但有几种方法可以描述您的需求。

选项1 - 模型继承

只要您在模型之间有一个共同的字段并且可以用来区分它们,就可以使用模型继承:

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

在您的示例中,此属性为typetype="BBANDS"type="DEMA")。所以你可以:

  • 使用BBANDSDEMA继承IndicatorallOf个模型。
  • discriminator: type添加到Indicator,以表明type属性将用于区分子模型。
  • Payload定义为Indicator的数组。这样它实际上可以是BBANDS的数组或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

选项2 - 单一模型

如果所有parameters都是整数,则可以将单个模型Indicatorparameters定义为散列映射。但在这种情况下,您将失去为特定指标类型定义精确parameters的能力。

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

答案 1 :(得分:-1)

数组类型的AFAIK可以包含一种类型,如果你想在一个数组下有多个类型,那么需要定义另一个超类型并在其中包装子类型(可能使用对象类型),如下图所示。这种限制是因为swagger-2.0不支持json-schema.org的所有功能,oneOfanyOfallOf等等。

但是你可以使用swagger-2.0提供的第三方扩展选项。您可以在其中使用x-命名密钥,这意味着您可以包含oneOf这些x-oneOf,并在解析模式时使用json-schema解析器以及swagger模式解析器。

下面给出了一个这样的例子,

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"
        }
      ]
    }
  }
}

数据或有效负载

{
"storage": {"label": "adsf"},
"deviceList": [{"label": "asdf"}, {"blockId": 23}, {"charDeviceName": "asdf"}]
}

使用此网站来播放您的示例数据 - http://www.jsonschemavalidator.net/

注意deviceList属性及其构造方式。希望这会对你有所帮助。