Search code examples
swagger-2.0swagger-editor

Swagger editor object properties


I'm getting started with the Swagger Editor and I'm a little confused on reusable definitions. As an example, I have a Task model defined as show below.

GET

The GET call will return all elements that are a part of the Task model.

POST

A POST call must specify task_list_id, title and display_order. It may contain notes, due, assigned_id and parent_id. No other elements should be sent from the Task object.

PATCH

A PATCH call would not send in the ident as that would be part of the path URL, but it would send in one or more of the other elements.

If completed is specified then completor_id should also be specified (I'm OK with this one just being specified in the comments of the PATCH method...

definitions:
  Task:
    properties:
      ident:
        type: integer
        description: The SQL ident of the Task object
        readOnly: true
      task_list_id:
        type: integer
        description: The SQL ident of the Task List object this Task belongs to.
      assigned_id:
        type: integer
        description: The SQL ident of the Person who this task is assigned to.
      completor_id:
        type: integer
        description: The SQL ident of the Person who completed this task.
      created:
        type: integer
        description: The UTC epoch time this Task was created.
      completed:
        type: integer
        description: The UTC epoch time this Task was completed.
      due:
        type: integer
        description: The UTC epoch time this Task will be due.
      title:
        type: string
        description: The details of the Task
      notes:
        type: string
        description: Extra notes to clarify the Task requirements.
      display_order:
        type: integer
        description: The order that this task should be displayed in user visible lists.
      parent_id:
        type: integer
        description: The SQL ident of the Task that this is a sub-Task of.

Solution

  • In your example, you will need to define separate models for GET, PUT and PATCH and duplicate the properties in each model.

    Why: While Swagger supports model inheritance/composition to some extent, your models cannot be inherited from each other because they all have different required properties. Extending the base model and at the same time overriding its required properties is not supported.


    However, if you are writing YAML manually (rather than generating it from code), you may be able to avoid code duplication by using YAML features such as anchors (&, *) and merge keys (<<). Whether this will work depends on whether your tool supports these YAML features.footnote Swagger Editor and Swagger UI support them but I don't know about other tools.

    Here's an example to help you get the idea:

    BaseModel:
      properties: &base-model-properties
         foo:
           type: string
    
    # Overriding the required properties
    OtherModel:
      properties: *base-model-properties
      required: [foo]
    
    # Extending with other properties
    YesAnotherModel:
      properties:
        <<: *base-model-properties
        bar:
          type: integer
    


    In your case you could use TaskForPost as the base model:

    definitions:
      TaskForPost:
        type: object
        properties: &BASE-TASK-PROPERTIES
          task_list_id:
            type: integer
          title:
            type: string
          display_order:
            type: integer
          notes:
            type: string
          due:
            type: integer
          assigned_id:
            type: integer
          parent_id:
            type: integer
        required:
          - task_list_id
          - title
          - display_order
    

    TaskForPatch would combine the base model's properties (aliased BASE-TASK-PROPERTIES) with a few more:

      TaskForPatch:
        type: object
        properties: &TASK-PATCH-PROPERTIES
          <<: *BASE-TASK-PROPERTIES
          completor_id:
            type: integer
            description: The SQL ident of the Person who completed this task.
          created:
            type: integer
            description: The UTC epoch time this Task was created.
          completed:
            type: integer
            description: The UTC epoch time this Task was completed.
        minProperties: 1
    

    TaskForGet would reuse TaskForPatch's properties (aliased TASK-PATCH-PROPERTIES) and add an extra property ident:

      TaskForGet:
        type: object
        properties:
          <<: *TASK-PATCH-PROPERTIES
          ident:
            type: integer
            description: The SQL ident of the Task object
        required:
          - ident
          - title
          # etc.
    

    If completed is specified then completor_id should also be specified (I'm OK with this one just being specified in the comments of the PATCH method.

    Swagger models does not support property dependencies. This can only be documented verbally in the operation description or model description.


    footnote Anchors are a built-in feature of YAML 1.2, but merge keys are not -- they are an extra feature that parsers can choose to implement (or not). But even anchors may be not supported fully in some implementations.