tomhre
tomhre

Reputation: 315

Swagger Nested Array of Objects

i was asked to use swagger to describe the API and I struggle to get the more complex situations to work. Imagine you are posting Order with multiple order items

<upload_order>
<token>d6a91238b0f17b49d49fbdcbba773d71</token>
<order>
    <order_id>10006</order_id>
    <item_value>48.50</item_value>
    <postage_value>5.00</postage_value>
    <gross_value>A43.50</gross_value>
    <discount_value>10.00</discount_value>
    <delivery_date>2016-10-32</delivery_date>
    <customer_name>Tom H</customer_name>
    <business_name>Toysorry</business_name>
    <address_line_1>Adderss Line 1</address_line_1>
    <address_line_2>Adderss Line 1</address_line_2>
    <town>Town</town>
    <county>County</county>
    <postcode>PO123ST</postcode>
    <email>[email protected]</email>
    <telephone>0787878787878</telephone>
    <delivery_instructions>Garage</delivery_instructions>
    <delivery_method>PRE12</delivery_method>
    <items>
        <item>
            <id>1</id>
            <sku>BLABLA</sku>
            <qty>A</qty>
            <product_name>A Product</product_name>
            <unit_price>1.50</unit_price>
        </item>
        <item>
            <id>2</id>
            <sku>HAHAHA</sku>
            <qty>2</qty>
            <product_name>WINTER BUNDLE</product_name>
            <unit_price>22.00</unit_price>
        </item>
    </items>
</order>

how can i describe it in swagger, since usage of array in this way does not seem to play

/upload_order:
post:
  description: create order
  operationId: upload_order
  produces:
    - application/xml
  parameters:
    - name: upload_order
      in: body
      description: upload order
      required: true
      schema:
        $ref: '#/definitions/newOrder'
  responses:
    '200':
      description: response
      schema:
        $ref: '#/definitions/token_response'
    default:
      description: unexpected error
      schema:
        $ref: '#/definitions/errorModel'



newOrder:
    type: object
    required:
      - token
      - order_id
      - item_value
      - postage_value
      - gross_value
      - discount_value
      - delivery_date
      - customer_name
      - business_name
      - address_line_1
      - address_line_2
      - town
      - county
      - postcode
      - email
      - telephone
      - delivery_instructions
      - delivery_method
      - items
    properties:
      token:
        type: string
      order_id:
        type: string
      item_value:
        type: number
        format: float
      postage_value:
        type: number
        format: float
      gross_value:
        type: number
        format: float
      discount_value:
        type: number
        format: float
      delivery_date:
        type: string
        format: date
      customer_name:
        type: string
      business_name:
        type: string
      address_line_1:
        type: string
      address_line_2:
        type: string
      town:
        type: string
      county:
        type: string
      postcode:
        type: string
      email:
        type: string
      telephone:
        type: string
      delivery_instructions:
        type: string
      delivery_method:
        type: string
      items:
        $ref: '#/definitions/itemsArray'
  itemsArray:
    type: array
    required: item
    item:
      $ref: '#/definitions/item'
  item:
    required:
      - id
      - sku
      - qty
      - product_name
      - unit_price
    type: object
    properties:
      id:
        type: string
      sku:
        type: string
      qty:
        type: integer
        format: int32
      product_name:
        type: string
      unit_price:
        type: number
        format: float

please save me

Thanks

UPDATE - I FIGURED FEW DAYS LATER BASED ON FULL PET SHOP MARKUP, FORGOT TO POST THE ANSWER, EASY POINT FOR SOME

paths:
  /upload_order:
    post:
      description: create order
      operationId: upload_order
      parameters:
        - name: upload_order
          in: body
          description: upload order
          required: true
          schema:
            $ref: '#/definitions/uploadOrder'
      responses:
        '200':
          description: response
          schema:
            $ref: '#/definitions/upload_response'
        default:
          description: unexpected error
          schema:
            $ref: '#/definitions/errorModel'
definitions:
  uploadOrder:
    type: object
    required:
      - upload_order
    properties:
      upload_order:
        $ref: '#/definitions/uploadOrderData'
  uploadOrderData:
    type: object
    required:
      - login
      - order
    properties:
      login:
        $ref: '#/definitions/login'
      order:
        $ref: '#/definitions/order'
  order:
    type: object
    required:
      - order_id
      - address_line_2
      - items
    properties:
      order_id:
        type: string
      item_value:
        type: string
        pattern: '^(\d{1,100}\.\d{2})$'
        default: '0.00'
      postage_value:
        type: string
        pattern: '^(\d{1,100}\.\d{2})$'
        default: '0.00'
      gross_value:
        type: string
        pattern: '^(\d{1,100}\.\d{2})$'
        default: '0.00'
      discount_value:
        type: string
        pattern: '^(\d{1,100}\.\d{2})$'
        default: '0.00'
      delivery_date:
        type: string
        format: date
      customer_name:
        type: string
      business_name:
        type: string
      address_line_1:
        type: string
      address_line_2:
        type: string
      town:
        type: string
      county:
        type: string
      postcode:
        type: string
      email:
        type: string
      telephone:
        type: string
      delivery_instructions:
        type: string
      delivery_method:
        type: string
      items:
        $ref: '#/definitions/orderItems'
  orderItems:
    type: array
    required:
      - item
    properties:
      item:
        $ref: '#/definitions/orderItem'
    items:
      $ref: '#/definitions/orderItem'
  orderItem:
    required:
      - id
      - sku
      - qty
      - product_name
      - unit_price
    type: object
    properties:
      id:
        type: string
      sku:
        type: string
      qty:
        type: integer
        format: int32
      product_name:
        type: string
      unit_price:
        type: string
        pattern: '^(\d{1,100}\.\d{2})$'
        default: '0.00'
  login:
    type: object
    required:
      - login
    properties:
      login:
        $ref: '#/definitions/login_data'
  login_data:
    type: object
    required:
      - username
      - password
      - channel_code
    properties:
      username:
        type: string
      password:
        type: string
      channel_code:
        type: string
  upload_response:
    type: object
    properties:
      response:
        $ref: '#/definitions/upload_response_data'
  upload_response_data:
    type: object
    required:
      - messages
      - success
    properties:
      messages:
        $ref: '#/definitions/messages'
      success:
        type: string
  errorModel:
    type: object
    required:
      - messages
    properties:
      messages:
        $ref: '#/definitions/messages'
  messages:
    type: array
    required:
      - message
    properties:
      message:
        $ref: '#/definitions/message'
    items:
      $ref: '#/definitions/message'
  message:
    type: string

Upvotes: 5

Views: 23878

Answers (1)

dwu
dwu

Reputation: 426

Based on your XML document it seems that you won't need the type itemsArray. You could try to simplify the definition of newOrder by referencing the item type in items directly. Here are the relevant parts of the modified type definition.

definitions:
  newOrder:
      type: object
      ...
      properties:
        ...
        delivery_method:
          type: string
        items:
          type: array
          items:
            $ref: '#/definitions/item'

  item:
      ...
      type: object
      properties:
        id:
          type: string
        ...

The resulting data structure looks like this: enter image description here

An additional note: as token is outside of the order element in your XML document you probably need to split your newOrder type into two and move token to the outer element. To give you an idea here's an example with all properties except token moved to the nested element order.

  newOrder:
    properties:
      token:
        type: string
      order:
        type: array
        items:
          $ref: '#/definitions/order'
  order:
    properties:
      order_id:
        type: string
      ...

Resulting type definition: enter image description here

Upvotes: 9

Related Questions