Refer to self in OpenAPI 3.0 - swagger-ui

I have a data model definition in OpenAPI 3.0, using SwaggerHub to display the UI. I want one of the properties of a model to be related, which is an array of properties of the same model.
Foo:
properties:
title:
type: string
related:
type: array
items:
$ref: '#/components/schemas/Foo'
The parser doesn't seem to like this - the UI shows the related property as an empty array. Is this kind of self-reference possible in OpenAPI 3.0?

Your definition is correct, it's just Swagger UI currently does not render circular-referenced definitions properly. See issue #3325 for details.
What you can do is add a model example, and Swagger UI will display this example instead of trying to generate an example from the definition.
Foo:
type: object
properties:
title:
type: string
related:
type: array
items:
$ref: '#/components/schemas/Foo'
example: # <-------
title: foo
related:
- title: bar
- title: baz
related:
- title: qux
Alternatively, you can add an example just for the related array:
Foo:
type: object
properties:
title:
type: string
related:
type: array
items:
$ref: '#/components/schemas/Foo'
example: # <--- Make sure "example" is on the same level as "type: array"
- title: bar
- title: baz
related:
- title: qux

I got tired of this pesky situation, so I went with no example at all and chose to get rid of the items property, add a description element and use an empty array instead:
Foo:
type: object
properties:
title:
type: string
related:
type: array
description: Array of Foo elements
example: []

You can achieve that by a proxy model:
...
_MessageProxy:
description: Message
type: object
required:
- id
- user
- body
- publishedAt
properties:
id:
title: Message id
type: string
readOnly: true
example: '595f4acf828b0b766ad11290'
user:
$ref: '#/components/schemas/User'
Message:
allOf:
- $ref: '#/components/schemas/_MessageProxy'
- type: object
properties:
parent:
title: Parent
readOnly: true
allOf:
- $ref: '#/components/schemas/_MessageProxy'
...

Using a dummy model and cross reference:
Foo:
properties:
title:
type: string
related:
type: array
items:
$ref: '#/components/schemas/_Foo'
_Foo:
properties:
title:
type: string
related:
type: array
items:
$ref: '#/components/schemas/Foo'

Related

Swagger - discriminator: resouce_type does not show in UI

I'm using discriminator: resouce_type in my YAML for some of the definitions. They are not showing on UI. Can someone please help, is it supported in swagger UI or Am I doing something wrong..
Swagger/OpenAPI definition:
definitions:
myModel:
allOf:
- $ref: '#/definitions/ResponseWrapper'
- type: object
type: object
properties:
field1:
type: number
format: string
description: "My field 1"
field2:
type: string
description: "My field 2"
ResponseWrapper:
allOf:
- type: object
discriminator: resouce_type
Swagger-UI configuration options:
SwaggerUI({
"library": "spring-mvc",
"dateLibrary": "legacy",
"hideGenerationTimestamp": true,
"modelPackage": "com.example",
"apiPackage": "com.example",
"useTags": true,
"importMappings": {
"ResponseWrapper": "com.example.ResponseWrapper"
}
}
)
Can swagger read those classes from classpath and resolve and show in UI.?

Object of object of array in Swagger

I have an input in the below format:
{"value" : {"codes": ["123","234"]} }
I have a swagger document as below but it does not yield the above result
/v1/search:
post:
summary: Get values
description: Get values
parameters:
- name: value
in: body
schema:
properties:
value:
type: array
items:
$ref: "#/definitions/Values"
definitions:
Values:
type: object
properties:
codes:
type: string
Any leads would be appreciated.
Try this. I used Value and Codes as schema names, but feel free to change them as you see fit.
- name: value
in: body
schema:
$ref: '#/definitions/Value'
definitions:
Value:
type: object
properties:
value:
$ref: '#/definitions/Codes'
Codes:
type: object
properties:
codes:
type: array
items:
type: string

How can I override example in openapi spec?

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'

Using $refs in Open Api 3.0.x yaml format, Swagger

I am trying to document an api on swagger (Open api 3.0.x) and I find a problems using $refs.
As written here, it's working as intended, BUT debugger shows an error my request body definition (it lacks content, application/json, schema)
What is the correct way to do this?
/foobarbaz:
post:
requestBody:
description: lorem ipsum
content:
application/json:
schema:
oneOf:
- $ref: '#/components/requestBodies/foo'
- $ref: '#/components/requestBodies/bar'
- $ref: '#/components/requestBodies/baz'
examples:
foo:
$ref: '#/components/examples/foo'
bar:
$ref: '#/components/examples/bar'
baz:
$ref: '#/components/examples/baz'
components:
requestBodies:
foo: <-- here it highlights (Missing property "$ref".)
schema
type: object
properties:
foo:
type: string
bar:
type: string
bar: <-- here it highlights (Missing property "$ref".)
schema
type: object
properties:
foo:
type: string
bar:
type: string
baz: <-- here it highlights (Missing property "$ref".)
schema
type: object
properties:
foo:
type: string
bar:
type: string
examples:
foo:
value:
foo: 'bar'
bar: '20'
bar:
value:
foo: 'bar'
bar: '20'
baz:
value:
foo: 'bar'
bar: '20'
oneOf can only $ref schemas, not requestBody components. Here's the correct version:
/foobarbaz:
post:
requestBody:
description: lorem ipsum
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/foo' # <--- $refs point to schemas, not requestBodies
- $ref: '#/components/schemas/bar'
- $ref: '#/components/schemas/baz'
examples:
...
components:
schemas: # <--- Put the schemas in the "schemas" section rather than "requestBodies"
foo:
type: object
properties:
foo:
type: string
bar:
type: string
bar:
type: object
properties:
foo:
type: string
bar:
type: string
baz:
type: object
properties:
foo:
type: string
bar:
type: string

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'

Resources