How can I override example in openapi spec? - swagger

I've got the following spec:
---
openapi: 3.0.0
info:
title: Players API
version: 0.0.1-alpha1
paths:
/players/{id}:
get:
responses:
'200':
description: OK
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/PlayerWrapper'
components:
schemas:
PlayerWrapper:
type: object
properties:
display_name:
type: string
example: 76ers
config:
description: |
The configuration of the player.
example: { spec: { team: 76ers, names: [ 1, 2 ] } }
allOf:
- $ref: '#/components/schemas/Player'
Player:
type: object
properties:
spec:
allOf:
- $ref: '#/components/schemas/BasicPlayer'
additionalProperties: false
BasicPlayer:
type: object
properties:
team:
type: string
names:
allOf:
- $ref: '#/components/schemas/Names'
additionalProperties: false
Names:
type: array
items:
type: string
example: [ Ben, Joel ]
I did verify on Swagger that it's indeed valid. The question is why I can see names: [ 1, 2 ] other than [ Ben, Joel ]. When I do remove that example thing (# example: { spec: { team: 76ers, names: [ 1, 2 ] } }), I can see Ben, Joel example:
Is there a way how I can force override / merge those example? As of now, I feel like my example gets overriden by either of those fields (i.e., either 76ers / [1, 2] or string / [Ben, Joel] but I'd like to get 76ers / [Ben, Joel] instead).

The structure in your schemas isn't quite right. The idea is to provide examples on the simple types (strings, int, etc) and the schema will structure it as required.
So dont put the example on config, put it on the nested simple types like this, ie BasicPlayer object should have the example on team as it's a string:
BasicPlayer:
type: object
properties:
team:
type: string
example: '76ers'
names:
allOf:
- $ref: '#/components/schemas/Names'
Similar with PlayerWrapper.config don't try and give a full object in the example, it gets composed by the member properties. So team gets an example, but Names example is composed from the child type.
PlayerWrapper:
type: object
properties:
display_name:
type: string
example: '76ers'
config:
description: |
The configuration of the player.
allOf:
- $ref: '#/components/schemas/Player'
Which should give you the expected example:
Here's the full swagger:
---
openapi: 3.0.0
info:
title: Players API
version: 0.0.1-alpha1
paths:
/players/{id}:
get:
parameters:
- $ref: '#/components/parameters/id'
responses:
'200':
description: OK
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/PlayerWrapper'
components:
parameters:
id:
name: id
in: path
required: true
schema:
type: string
description: The id.
schemas:
PlayerWrapper:
type: object
properties:
display_name:
type: string
example: '76ers'
config:
description: |
The configuration of the player.
allOf:
- $ref: '#/components/schemas/Player'
Player:
type: object
properties:
spec:
allOf:
- $ref: '#/components/schemas/BasicPlayer'
additionalProperties: false
BasicPlayer:
type: object
properties:
team:
type: string
example: '76ers'
names:
allOf:
- $ref: '#/components/schemas/Names'
additionalProperties: false
Names:
type: array
items:
type: string
example:
- Ben
- Joel
Note it is possible to override schema examples with an example in the resource definition like this:
paths:
/players/{id}:
get:
parameters:
- $ref: '#/components/parameters/id'
responses:
'200':
description: OK
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/PlayerWrapper'
example:
display_name: 76ers
config:
spec:
team: 76ers
names:
- 'Ben'
- 'Joel'

Related

swagger example response not respecting nested allOf

When using the following swagger, the resulting endpoint has an example response that doesn't align with what I believe the swagger (and the models) dictate.
The swagger:
components:
examples: {}
headers: {}
parameters: {}
requestBodies: {}
responses: {}
schemas:
SubSubData:
type: object
properties:
subSubDataProp:
type: string
SubData:
allOf:
- $ref: '#/components/schemas/SubSubData'
- type: object
properties:
subDataProp:
type: string
Data:
allOf:
- $ref: '#/components/schemas/SubData'
- type: object
properties:
dataProp:
type: string
ExampleResponse:
type: object
properties:
data:
$ref: '#/components/schemas/Data'
info:
title: __PROJECT_NAME__
version: 1.0.0
description: |
Add your Swagger description here.
license:
name: ISC
contact:
name: Me
openapi: 3.0.0
paths:
/example:
get:
operationId: GetData
responses:
'200':
description: Ok
content:
application/json:
schema:
$ref: '#/components/schemas/ExampleResponse'
security: []
The expected response:
{
"data": {
"dataProp": "string",
"subDataProp": "string",
"subSubDataProp": "string"
}
}
Actual:
{
"data": {
"dataProp": "string"
}
}
Am I missing something? Or is this a bug in the swagger ui/openapi
It's a bug in Swagger UI:
https://github.com/swagger-api/swagger-ui/issues/5972
The workaround is to move paths before components.

OpenAPI 3.0 - How to avoid adding "value" key when including examples by ref

With OpenAPI Is there a way to include examples by reference with the $ref: tag that doesn't not require adding the "value" key?
See examples I've added to the petstore.yaml:
openapi: "3.0.0"
info:
version: 1.0.0
title: Swagger Petstore
license:
name: MIT
servers:
- url: http://petstore.swagger.io/v1
paths:
/pets:
get:
summary: List all pets
operationId: listPets
tags:
- pets
parameters:
- name: limit
in: query
description: How many items to return at one time (max 100)
required: false
schema:
type: integer
format: int32
responses:
'200':
description: A paged array of pets
headers:
x-next:
description: A link to the next page of responses
schema:
type: string
content:
application/json:
schema:
$ref: "#/components/schemas/Pets"
example:
$ref: "#/components/examples/animals"
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
post:
summary: Create a pet
operationId: createPets
tags:
- pets
responses:
'201':
description: Null response
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/pets/{petId}:
get:
summary: Info for a specific pet
operationId: showPetById
tags:
- pets
parameters:
- name: petId
in: path
required: true
description: The id of the pet to retrieve
schema:
type: string
responses:
'200':
description: Expected response to a valid request
content:
application/json:
schema:
$ref: "#/components/schemas/Pet"
example:
$ref: "#/components/examples/garfield"
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
components:
schemas:
Pet:
type: object
required:
- id
- name
properties:
id:
type: integer
format: int64
name:
type: string
tag:
type: string
Pets:
type: array
items:
$ref: "#/components/schemas/Pet"
Error:
type: object
required:
- code
- message
properties:
code:
type: integer
format: int32
message:
type: string
examples:
garfield:
id: 1
name: garfield
tag: cat
grumpycat:
id: 2
name: grumpycat
tag: cat
odie:
id: 3
name: odie
tag: dog
animals:
- $ref: "#/components/examples/garfield"
- $ref: "#/components/examples/grumpycat"
- $ref: "#/components/examples/odie"
openapi-generator-cli validate says it's invalid OpenAPI as does my OpenAPI plugin for VSCode. Error log output:
Validating spec (/local/petstore.yaml)
Errors:
-attribute components.examples.odie.name is unexpected
-attribute components.examples.garfield.id is unexpected
-attribute components.examples.grumpycat.name is unexpected
-attribute components.examples.animals is not of type `object`
-attribute components.examples.garfield.tag is unexpected
-attribute components.examples.garfield.name is unexpected
-attribute components.examples.odie.tag is unexpected
-attribute components.examples.grumpycat.id is unexpected
-attribute components.examples.grumpycat.tag is unexpected
-attribute components.examples.odie.id is unexpected
[error] Spec has 10 errors.
I can correct the errors by adding a value key like this:
examples:
garfield:
value:
id: 1
name: garfield
tag: cat
grumpycat:
value:
id: 2
name: grumpycat
tag: cat
odie:
value:
id: 3
name: odie
tag: dog
animals:
value:
- $ref: "#/components/examples/garfield"
- $ref: "#/components/examples/grumpycat"
- $ref: "#/components/examples/odie"
The problem with this is that, my examples now include the value property, which I don't want as it's not part of the schema:
{
"value": {
"id": 1,
"name": "garfield",
"tag": "cat"
}
}
Question: Is there a way for me to define the examples by $ref as I have done WITHOUT using introducing the "value" property?
The correct syntax is as follows:
components:
examples:
garfield:
value:
id: 1
name: garfield
tag: cat
grumpycat:
value:
id: 2
name: grumpycat
tag: cat
odie:
value:
id: 3
name: odie
tag: dog
animals:
summary: An array of two animals
value:
- id: 1
name: garfield
tag: cat
- id: 2
name: grumpycat
tag: cat
paths:
/pets:
get:
...
responses:
'200':
description: A paged array of pets
...
content:
application/json:
schema:
$ref: "#/components/schemas/Pets"
examples:
animals:
$ref: "#/components/examples/animals"
/pets/{petId}:
get:
...
responses:
'200':
description: Expected response to a valid request
content:
application/json:
schema:
$ref: "#/components/schemas/Pet"
examples:
garfield:
$ref: "#/components/examples/garfield"
grumpycat:
$ref: '#/components/examples/grumpycat'
odie:
$ref: '#/components/examples/odie'
Explanation:
Examples in the components/examples section must use the Example Object syntax. That is, the actual example value must be wrapped into the value key.
To reference examples from the components/examples section, you must use the examples keyword (plural; not singular example). examples is supported in parameters and in media types, but not in schemas.
Within the literal example value, $ref is not supported. That is, you cannot $ref a part of an example.

Multiple levels discriminators OpenAPI

Greeetings and thanks for your time.
I'm doing some ReDoc documenting using OpenAPI but can't find a way to properly make two levels inheritance. This is kinda what I have:
components:
schemas:
Pet:
type: object
required:
- pet_type
properties:
pet_type:
type: string
discriminator:
propertyName: pet_type
mapping:
dogs: Dog
cats: Cat
Cat:
allOf:
- $ref: '#/components/schemas/Pet'
- type: object
# all other properties specific to a `Cat`
properties:
name:
type: string
Dog:
allOf:
- $ref: '#/components/schemas/Pet'
- type: object
# all other properties specific to a `Dog`
properties:
bark:
type: string
size:
type: string
discriminator:
propertyName: size
mapping:
large: '#/components/schemas/LargeDog'
medium: '#/components/schemas/MediumDog'
SmallDogs:
allOf:
- $ref: '#/components/schemas/Dog'
- type: object
LargeDogs:
allOf:
- $ref: '#/components/schemas/Dog'
- type: object
Thanks in advance.
You are doing something weird or your example does not fully reveal the essence of the problem. For a dog size, you do not need to use the discriminator. Example below
components:
schemas:
Pet:
type: object
required:
- pet_type
properties:
pet_type:
type: string
discriminator:
propertyName: pet_type
mapping:
dogs: Dog
cats: Cat
Cat:
allOf:
- $ref: '#/components/schemas/Pet'
- type: object
# all other properties specific to a `Cat`
properties:
name:
type: string
Dog:
allOf:
- $ref: '#/components/schemas/Pet'
- type: object
# all other properties specific to a `Dog`
properties:
bark:
type: string
size:
type: string
enum:
- large
- medium

How to return an array of objects in SwaggerHub?

I am defining an API specification in SwaggerHub using OpenAPI 2.0. The /contacts request returns an array of contacts. The definition is below:
/contacts:
get:
tags:
- contacts
summary: Get all the contacts
description: This displays all the contacts present for the user.
operationId: getContact
produces:
- application/json
- application/xml
responses:
200:
description: successful operation
schema:
$ref: '#/definitions/AllContacts'
400:
description: Invalid id supplied
404:
description: Contact not found
500:
description: Server error
definitions:
AllContacts:
type: array
items:
- $ref: '#/definitions/ContactModel1'
- $ref: '#/definitions/ContactModel2'
ContactModel1:
type: object
properties:
id:
type: integer
example: 1
firstName:
type: string
example: 'someValue'
lastName:
type: string
example: 'someValue'
ContactModel2:
type: object
properties:
id:
type: integer
example: 2
firstName:
type: string
example: 'someValue1'
lastName:
type: string
example: 'someValue1'
For some reason, it only returns the second object not the whole array of objects.
I am using OpenAPI 2.0 and suspect that the arrays are not well supported in this version.
An array of objects is defined as follows. The value of items must be a single model that describes the array items.
definitions:
AllContacts:
type: array
items:
$ref: '#/definitions/ContactModel'
ContactModel:
type: object
properties:
id:
type: integer
example: 1
firstName:
type: string
example: Sherlock
lastName:
type: string
example: Holmes
By default, Swagger UI displays the array examples with just one item, like so:
[
{
"id": 1,
"firstName": "Sherlock",
"lastName": "Holmes"
}
]
If you want the array example to include multiple items, specify the multi-item example in the array model:
definitions:
AllContacts:
type: array
items:
$ref: '#/definitions/ContactModel1'
example:
- id: 1
firstName: Sherlock
lastName: Holmes
- id: 2
firstName: John
lastName: Watson
I realise this is a bit offtopic, but I landed here looking for an example for OpenApi 3.0. For others looking for the same thing, this is how to do it:
paths:
/product-category:
get:
summary: 'Returns all product categories'
operationId: readProductCategory
tags:
- productCategory
responses:
'200':
description: 'Details about all product categories'
content:
application/json:
schema:
type: array
items:
allOf:
- $ref: '#/components/schemas/Identifier'
- $ref: '#/components/schemas/ProductCategory'

Swagger Parameters and Complex Types

In the following Swagger definition, I need the parameter labelValue to be of type LabelValueObject, so that it will be validated and correctly deserialized. However, I can't figure out the syntax! How can that be done?
swagger: "2.0"
paths:
/competition:
post:
parameters:
- name: labelValue
in: formData
type: array
items:
type: string ### this has to be a LabelValueObject ###
responses:
default:
description: Error
schema:
$ref: "#/definitions/AnyResponse"
definitions:
AnyResponse:
properties:
any:
type: string
LabelValueObject:
properties:
label:
type: string
value:
type: string
required:
- label
- value
The only way to pass an object as a parameter is to put it in the body (in: body) and then define this object in schema (inline definition or reference to an predefined object with $ref). Here's a full example:
swagger: "2.0"
info:
title: A dummy title
version: 1.0.0
paths:
/competition:
post:
parameters:
- name: labelValue
in: body
schema:
$ref: '#/definitions/LabelValueObject'
responses:
default:
description: Error
schema:
$ref: "#/definitions/AnyResponse"
definitions:
AnyResponse:
properties:
any:
type: string
LabelValueObject:
properties:
label:
type: string
value:
type: string
required:
- label
- value

Resources