Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you create a swagger schema that includes an array of varying types

I'm attempting to define a swagger schema definition for an object that contains an array of objects of varying types.

Here is the json schema for a template object (and all related object types). I'm aware that swagger does not support the oneOf predicate, so I'm just trying to figure out how to describe this data structure in swagger. I've tried many variations on this syntax, but none have worked and this was the closest I could come based on the spec and some examples found here: http://json-schema.org/example2.html

swagger: '2.0'
info:
  version: 1.0.0
  title: IDMU
paths:

definitions:
  template:
    type: object
    properties:
      collection:
        type: string
      name:
        type: string
      columnValue:
        type: string
      description:
        type: string
      outputFile:
        type: string
      content:
        type: string
      directives:
        type: array
        items:
          type: object
          oneOf: 
            - 
              $ref: '#/definitions/directiveRequire'
            - 
              $ref: '#/definitions/directiveReplace'
            - 
              $ref: '#/definitions/directiveReplaceRowSql'
            - 
              $ref: '#/definitions/directiveReplaceRowCsv'
            - 
              $ref: '#/definitions/directiveReplaceColSql'
            - 
              $ref: '#/definitions/directiveReplaceColCsv'
            - 
              $ref: '#/definitions/directiveInsertTag'
            - 
              $ref: '#/definitions/directiveInsertCsv'
            - 
              $ref: '#/definitions/directiveInsertSql'
  providerCsv:
    type: object
    properties:
      type:
        type: integer
        maximum: 3
        minimum: 3
      tag:
        type: string
      url:
        type: string
      staticData:
        type: string
  providerTag:
    type: object
    properties:
      type:
        type: integer
        maximum: 2
        minimum: 2
      tag:
        type: string
      condition:
        type: integer
      list:
        type: boolean
      value:
        type: string
  providerSql:
    type: object
    properties:
      type:
        type: integer
        maximum: 1
        minimum: 1
      source:
        type: string
      columns:
        type: string
      from:
        type: string
      where:
        type: string
  directive:
    type: object
    discriminator: type
    properties:
      type:
        type: integer
      softFail:
        type: boolean
    required:
      - type
  directiveRequire:
    type: object
    allOf:
      - $ref: '#/definitions/directive'
      - properties:
          tags:
            type: array
            items:
              type: string
  directiveReplace:
    type: object
    allOf:
      - $ref: '#/definitions/directive'
      - properties:
          description:
            type: string
          from:
            type: string
          to:
            type: string
  directiveReplaceRowSql:
    type: object
    allOf:
      - $ref: '#/definitions/directive'
      - properties:
          description:
            type: string
          provider:
            $ref: '#/definitions/providerSql'
  directiveReplaceRowCsv:
    type: object
    allOf:
      - $ref: '#/definitions/directive'
      - properties:
          description:
            type: string
          provider:
            $ref: '#/definitions/providerCsv'
  directiveReplaceColCsv:
    type: object
    allOf:
      - $ref: '#/definitions/directive'
      - properties:
          description:
            type: string
          fromColumn:
            type: string
          toColumn:
            type: string
          provider:
            $ref: '#/definitions/providerCsv'
  directiveReplaceColSql:
    type: object
    allOf:
      - $ref: '#/definitions/directive'
      - properties:
          description:
            type: string
          fromColumn:
            type: string
          toColumn:
            type: string
          provider:
            $ref: '#/definitions/providerSql'
  directiveInsertTag:
    type: object
    allOf:
      - $ref: '#/definitions/directive'
      - properties:
          description:
            type: string
          notLast:
            type: array
            items:
              type: string
          onlyLast:
            type: array
            items:
              type: string
          provider:
            $ref: '#/definitions/providerTag'
      directiveInsertSql:
        type: object
        allOf:
          - $ref: '#/definitions/directive'
          - properties:
              description:
                type: string
              notLast:
                type: array
                items:
                  type: string
              onlyLast:
                type: array
                items:
                  type: string
              provider:
                $ref: '#/definitions/providerSql'
      directiveInsertCsv:
        type: object
        allOf:
          - $ref: '#/definitions/directive'
          - properties:
              description:
                type: string
              notLast:
                type: array
                items:
                  type: string
              onlyLast:
                type: array
                items:
                  type: string
              provider:
                $ref: '#/definitions/providerCsv'
like image 230
Mike Storey Avatar asked Mar 30 '16 20:03

Mike Storey


People also ask

What is schema in swagger?

OpenAPI 3.0 data types are based on an extended subset JSON Schema Specification Wright Draft 00 (aka Draft 5). The data types are described using a Schema object. To learn how to model various data types, see the following topics: Data Types.

How do you declare an empty array in swagger?

You can specify an empty array [] as an example for your array schema. This will override the default examples values generated by Swagger UI. Show activity on this post. shows your users that photoUrls is an array of strings.

Is swagger a JSON schema?

Swagger supports only subset of JSON Schema Draft 4 Specification of Swagger 1.2 and 2.0 states, it supports only subset of JSON Schema Draft 4 (s. here). This means, that: one cannot rely, that each valid JSON Schema can be completely supported by Swagger.


3 Answers

OpenAPI 3.0 supports oneOf and anyOf:

      schema:
        type: array
        items:
          oneOf:
            - $ref: '#/components/schemas/directiveRequire'
            - $ref: '#/components/schemas/directiveReplace'
            - ...

In OpenAPI 2.0, you can define an object with varying properties as just type: object (free-form object). For your case, you may want to do this:

      schema:
        type: array
        items:
          type: object
like image 188
William Cheng Avatar answered Oct 05 '22 11:10

William Cheng


You can set the items: reference to the base type. The inheritance model will vary by language during export from swagger specifically, but in practice method definitions specify the acceptable parameter types using the base model if you want to be able to accept multiple subclasses that inherit the same base model.

Swagger snippet -

definitions:
  template:
    type: object
    properties:
      collection:
        type: string
      ...
      directives:
        type: array
        items:
          $ref: '#/definitions/directive'
  directive:
    type: object
    discriminator: type
    properties:
      type:
        type: integer
      softFail:
        type: boolean
    required:
      - type
  directiveRequire:
    allOf:
    - $ref: '#/definitions/directive'
    - type: object
      properties:
        tags:
          type: array
          items:
            type: string
  directiveReplace:
    allOf:
    - $ref: '#/definitions/directive'
    - type: object
      properties:
        description:
          type: string
        from:
          type: string
        to:
          type: string

pseudocode -

class template {
  // all the other properties
  directive[] directives;
  function addDirective(directive newDirective) {
    this.directives.push(newDirective);
  }
}

class directive {
  int type;
  boolean softFail;
}

class directiveRequire inherits directive {
 //inherits type, softFail
 string[] tags;
}

class directiveReplace {
  //inherits type, softFail
  string description;
  string from;
  string to;
}

template templateOne = new template();

directiveReplace directiveOne = new directiveReplace();
directiveOne.type = "replace";
directiveOne.softFail = false;
directiveOne.description = "first directive replace";
directiveOne.from = "first";
directiveOne.to = "one";

directiveRequire directiveTwo = new directiveRequire();
directiveTwo.type = "require";
directiveTwo.softFail = true;
directiveTwo.tags = ["second","directive"];

templateOne.addDirective(directiveOne);
templateOne.addDirective(directiveTwo);
like image 33
Josh Avatar answered Oct 05 '22 10:10

Josh


Sample API response that returns an array of videos

  responses:
    '200':
      description: An array of videos
      schema:
        type: array
        items:
          $ref: '#/definitions/Video' 

Reference

https://swagger.io/docs/specification/adding-examples/

like image 26
ipegasus Avatar answered Oct 05 '22 11:10

ipegasus