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?
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.
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.
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:
I didn't try yet. But should be possible to define Model like that.