How to make a field in a definition required for some operations and not others
Asked Answered
G

3

30

I'm writing my swagger definition in yaml. Say I have a definition that looks something like this.

paths:
  /payloads:
    post:
      summary: create a payload
      ...
      parameters:
      - in: body
        name: payload
        description: New payload
        required: true
        schema:
          $ref: "#/definitions/payload"
    put:
      summary: update a payload
      ...
      parameters:
      - in: body
        name: payload
        description: Updated existing payload
        required: true
        schema:
          $ref: "#/definitions/payload"
...
definitions:
  payload:
    properties:
      id:
        type: string
      someProperty:
        type: string
      ...

Is there a way that I can indicate that the id property of a payload is required for the PUT operation and is optional (or should not appear at all) for the POST operation?

Geosynclinal answered 17/6, 2015 at 15:27 Comment(0)
H
28

You would have to define the models separately.

However, you have options for the cases of exclusion and difference.

If you're looking to exclude, which is the easy case, create a model of with the excluded property, say ModelA. Then define ModelB as ModelA plus the additional property:

ModelB:
  allOf:
    - $ref: "#/definitions/ModelA"
    - type: object
      properties:
        id:
          type: string

If you're looking to define the difference, follow the same method above, and exclude the id from ModelA. Then define ModelB and ModelC as extending ModelA and add the id property to them, each with its own restrictions. Mind you, JSON Schema can allow you to follow the original example above for some cases to "override" a definition. However, since it is not really overriding, and one needs to understand the concepts of JSON Schema better to not make simple mistakes, I'd recommend going this path for now.

Heshum answered 17/6, 2015 at 18:18 Comment(3)
That is very useful. I would be interested in any further insight about these "overrides", as I would really like to avoid multiple models if possible. The schema docs appears to indicate that a definition override can be placed within the method "schema" section, provided an element is not "duplicated"... Are there any examples of this syntax?Playoff
Your answer got the bounty because there are no other options. But still I'm hoping there actualle exists alternatives. If anyone knows, please write an answer.Enos
Trust me, I wish there was. Unfortunately, JSON Schema is a validation language and not a modeling language, so it isn't really friendly to such (common) use cases.Heshum
D
0

My way to go about this is to define an 'abstract' model which contains all the parameters. Then for each usecase, I will define a model that references the first one and indicates exactly what are the required fields.

paths:
  /payloads:
    post:
      summary: create a payload
      ...
      parameters:
      - in: body
        name: payload
        description: New payload
        required: true
        schema:
          $ref: "#/definitions/NewPayload"
    put:
      summary: update a payload
      ...
      parameters:
      - in: body
        name: payload
        description: Updated existing payload
        required: true
        schema:
          $ref: "#/definitions/UpdatePayload"
...
definitions:
  # This payload would be used with update requests and has no required params.
  NewPayload:
     allOf:
       - { $ref: '#definitions/PayloadProperties }
       - type: object

  # This payload would be used with update requests and require an id param.
  UpdatePayload:
     allOf:
       - { $ref: '#definitions/PayloadProperties }
       - type: object
         required: [id]

  PayloadProperties:
    properties:
      id:
        type: string
      someProperty:
        type: string
      ...

I find this method rather clean as it doesn't require duplication, provides seperation of concerns and granularity.

Dashiell answered 21/3, 2018 at 15:49 Comment(1)
But in your NewPayload, you don't need the id property right? How do you manage things like that?Certes
T
0

I'm in the same problem rigth now. Im my case, I tried to override requerid block of model. But didn't work. =[ Then, I remembered we can add new properties of a $ref. So it works if you define the requeried fields on schema for each method. Some thing like this (Focus on required block for each ref):

swagger: '2.0'
info:
  title: API
  version: 0.0.1
host: api.help.v1
basePath: /help
schemes:
- https
definitions:
  MyModel:
    description: 'Exemplo'
    type: object
    properties:
      field_1:
        type: string
      field_2:
        type: string
      field_3:
        type: string
paths:
  '/helps':
    post:
      description: ''
      summary: ''
      parameters:
        - in: body
          name: payload
          schema:
            type: object
            allOf:
            - $ref: '#/definitions/MyModel'
            required: 
            - field_1
      responses:
        '200':
          description: OK
        '400':
          description: N_OK
    put:
      description: ''
      summary: ''
      parameters:
        - in: body
          name: payload
          schema:
            type: object
            allOf: 
            - $ref: '#/definitions/MyModel'
            required: 
            - field_2
      responses:
        '200':
          description: OK
        '400':
          description: N_OK

externalDocs:
  description: Find out more about Swagger
  url: 'http://swagger.io'

Oh! On swagger editor show that only by model view: enter image description here

I didn't try yet. But should be possible to define Model like that.

Tophet answered 16/7, 2018 at 15:11 Comment(1)
This is pretty great. However, the red star does not appear any longer in the current editor of Swagger. Also, it seems to me pretty crucial to be able to indicate which fields are required for which methods on a per-method basis. Or is this a thinking error?Gardner

© 2022 - 2024 — McMap. All rights reserved.