learn.openapis.org
learn.openapis.org copied to clipboard
Improve examples
@KES777 There's not really any difference between PUT and POST from the perspective of the OpenAPI description. Is there some specific thing you are looking for an example to demonstrate?
No. Just for purpose of completeness
Today I have good question. and can describe specific thing which is worth to demonstrate. For example we have next thing:
components:
schemas:
Country:
type: object
required:
- id
- code
properties:
id:
type: integer
readOnly: true
code:
type: string
name:
type: string
To create new country I have next path:
paths:
/countries:
post:
summary: Create a country
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/Country'
Thus to create country we send next json:
{
code: 'UA',
}
It is OK. Only code is required, id is readonly
But when we update this country we can send one of: code or name or both.
The schema may looks like:
paths:
/countries:
put:
summary: Update a country
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/Country'
But this will restrict us to send next API request PUT /api/countries/1:
{
name: 'some name',
}
Which will cause validation error:
`code` field is required
It seems I should define it via anyOf. Is this correct decision?
paths:
/countries:
put:
summary: Update a country
requestBody:
required: true
content:
application/json:
schema:
anyOf:
- $ref: '#/components/schemas/Country'
But this also requires code to be present in request.
How to describe: expect any of properties in Country?
@KES777, If I understand correctly, you want to have different constraints on the POST request, where you're creating a new Country, vs. the PUT request, where you're updating an existing country.
I think you can accomplish this with separate schema objects, defined like this:
components:
schemas:
# Base type for a Country, with minimal constraints
BaseCountry:
type: object
properties:
id:
type: integer
readOnly: true
code:
type: string
name:
type: string
# Country with at least one known property, used for PUT or PATCH requests.
NonEmptyCountry:
allOf:
- $ref: "#/components/schemas/BaseCountry"
# require at least one known property value.
minProperties: 1
additionalProperties: false
# additionalProperties doesn't have visibility into the inherited properties,
# so re-declare these:
properties:
id:
name:
code:
# Country object in its complete, steady state
Country:
allOf:
- $ref: "#/components/schemas/NonEmptyCountry"
required:
- id
Your put request can use NonEmptyCountry, which must have at least one of the known properties, excluding id which is readOnly.
Your post request can use Country or NonEmptyCountry, which are equivalent in the request context.
Responses that include an object representation should use Country, which requires id.
@tedepstein Thanks. You understand correct.
@tedepstein: I should not redeclare id for NonEmptyCountry because it must be excluded
Here is my variant of schema. I did it slightly differently. Maybe will be useful for others
We are moving supplementary examples to the learn.openapis.org site, so I am going to transfer this issue so it's easier to see what issues are for the separate examples and what are for the examples embedded in the spec. See this issue for the decision:
- OAI/OpenAPI-Specification#3854