I have a path that uses complex models with almost identical properties for each http method. The problem is that I want to define some required properties for the request of PUT and POST, while no properties are required in GET response (as the server always returns all properties and it's mentioned elsewhere in the documentation).
I created a simple cat API to demonstrate what I've tried. The idea is that for GET response the response model doesn't have anything marked as required, but the request of PUT must have a name for the cat.
swagger: "2.0"
info:
title: "Cat API"
version: 1.0.0
paths:
/cats/{id}:
parameters:
- name: id
in: path
required: true
type: integer
get:
responses:
200:
description: Return a cat
schema:
$ref: "#/definitions/GetCat"
put:
parameters:
- name: cat
in: body
required: true
schema:
$ref: "#/definitions/PutCat"
responses:
204:
description: Cat edited
definitions:
Cat:
type: object
properties:
name:
type: string
GetCat:
allOf:
- $ref: "#/definitions/Cat"
properties:
id:
type: integer
PutCat:
type: object
required:
- name
properties:
$ref: "#/definitions/Cat/properties"
Swagger Editor says that this is a valid specification, but name
is set as required for both GET and PUT. The same goes with Swagger UI.
I also tried the following version of PutCat:
PutCat:
type: object
required:
- name
allOf:
- $ref: "#/definitions/Cat"
But now everything is optional.
I can't figure this out. Is there a way to do this properly?
EDIT:
As Helen correctly mentioned, I can use readOnly
to solve this particular case with GET and PUT.
But let's say I add breed
property which must be provided (in addition to the name
property) for PUT. Then I add PATCH method, which can be used to update either breed
or name
while the other remains unchanged, and I want to set neither of those as required.
In your example, you can use a single model for both GET and POST/PUT, with properties only used in the GET response marked as readOnly
. From the spec:
readOnly
Declares the property as "read only". This means that it MAY be sent as part of a response but MUST NOT be sent as part of the request. Properties marked as readOnly being true SHOULD NOT be in the required list of the defined schema. Default value is false.
The spec would look like:
get:
responses:
200:
description: Return a cat
schema:
$ref: "#/definitions/Cat"
put:
parameters:
- name: cat
in: body
required: true
schema:
$ref: "#/definitions/Cat"
responses:
204:
description: Cat edited
definitions:
Cat:
properties:
id:
type: integer
readOnly: true
name:
type: string
breed:
type: string
required:
- name
- breed
This means you must PUT the name
and breed
:
{
"name": "Puss in Boots",
"breed": "whatever"
}
and GET /cats/{id}
must return the name
and breed
and may also return the id
:
{
"name": "Puss in Boots",
"breed": "whatever",
"id": 5
}