Swagger composition / inheritance

2.3k Views Asked by At

I'm trying to document a REST API using Swagger. A simplified JSON response from our API looks like:

{ 
    "data": {
        "type": "person"
        "id": "1"
        "attributes": {
          "name": "Joe"
          "age": 32
          ...
        }
        "links": {
            ...
        }
    }
}

or

{ 
    "data": {
        "type": "job"
        "id": "22"
        "attributes": {
          "name": "Manager"
          "location": "Somewhere"
          ...
        }
        "links": {
            ...
        }
    }
}

Their Swagger definitions for a successful GET might look like:

   '200':
      description: OK.
      schema:
        type: object
        properties:
          data:
            type: object
            properties:
              id:
                type: string
              type:
                type: string
              attributes:
                $ref: '#/definitions/person'

or

   '200':
      description: OK.
      schema:
        type: object
        properties:
          data:
            type: object
            properties:
              id:
                type: string
              type:
                type: string
              attributes:
                $ref: '#/definitions/job'

There's potentially a lot of repetition like this in our Swagger file. Is it possible to define these responses to share the common parts? i.e. I don't want to type out or copy/paste this part tens of times:

   '200':
      description: OK.
      schema:
        type: object
        properties:
          data:
            type: object
            properties:
              id:
                type: string
              type:
                type: string

I couldn't see how this would work using the discriminator field, or using $ref.

1

There are 1 best solutions below

1
On

You can use allOf to do composition (in conjunction with discriminator you can do inheritance but it's not really functionnal)

allOf is used with an array of schema or reference, it will create a new definition containing all properties of all definitions in the array.

Given that you want some of your definitions to share id and type properties, it is done this way:

swagger: '2.0'
info:
  version: 1.0.0
  title: API

paths: {}

definitions:
  SharedDefinition:
    properties:
      id:
        type: string
      type:
        type: string

  Person:
    allOf:
      - $ref: '#/definitions/SharedDefinition'
      - properties:
          firstname:
            type: string
          lastname:
            type: string

  JobSubDefinition:
    properties:
      name:
        type: string

  Job:
    allOf:
      - $ref: '#/definitions/SharedDefinition'
      - $ref: '#/definitions/JobSubDefinition'

In this example:

  • Person = SharedDefinition + inline definition
  • Job = SharedDefinition + JobSubDefinition

More about this in