openapi: referring to an existing example in a list - swagger

I have an OpenAPI 3.0.0 spec with a Widget component, which includes an example section:
components:
schemas:
Widget:
properties:
id:
type: string
description:
type: string
cost:
type: float
example:
id: 1234
description: An example widget
cost: 0.10
I'm adding a Warehouse component that includes a list of Widgets. Is there a way to make use of the example on the Widget schema in the Warehouse schema? Something like:
Warehouse:
properties:
id:
type: string
location:
type: string
widgets:
type: array
items:
$ref: '#/components/schemas/Widget'
example:
id: 4321
widgets:
- $ref: '#/components/schemas/Widget'
The above didn't work. I looked at moving the example out of the Widget schema and into a #/components/examples/WidgetExample, but I still wasn't sure what the syntax would look like to refer to that.

The example keyword does not support $ref.
What you can do instead is change the Warehouse schema to use property-level examples for properties other than widgets, in this case the example for widgets will be "inherited" from the Widget schema. At least this is how it works in Swagger UI and Swagger Editor.
Warehouse:
properties:
id:
type: string
example: 4321 # <----
location:
type: string
example: Sample location # <----
widgets:
type: array
items:
$ref: '#/components/schemas/Widget'
Swagger UI will display the following example for Warehouse in the requests and responses:
{
"id": 4321,
"location": "Sample location",
"widgets": [
"id": 1234,
"description": "An example widget",
"cost": 0.1
]
}

Related

Add the placeholder required in swagger ui v2.0

i got this swagger description:
APIExperimentProperties:
type: object
properties:
name:
type: "string"
experimentVariants:
type: array
items:
$ref: "#/definitions/APIExperimentVariantProperties"
owner:
type: "string"
label:
type: "string"
ticketId:
type: "string"
featureName:
type: "string"
APIExperimentVariantProperties:
type: object
required:
- id
- name
properties:
id:
type: "integer"
format: "int64"
name:
type: "string"
I wanted to make the fields id and name in APIExperimentVariantProperties to be marked as required in the swagger-ui.
As you can see in the picture, it looks like it worked.
It removed the optional from the field, and their labels are bolder
(the id field vs the featureName field for example).
But I am trying to make their placeholder say that it's required field, just like it did automatically for the field in the image below.
Any idea how to do that? the decimation didn't give any additional leads.

Swagger UI displaying array example as null

I use OpenAPI 3.0.0 and want to pass an array of Items as a parameter in the requestBody. My API definition looks like this:
post:
tags:
- test
summary: Test dummy
operationId: requestBodyTests
requestBody:
description: test the body
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/Items'
components:
schemas:
Items:
type: array
items:
$ref: '#/components/schemas/Item'
examples:
- id: bla
text: blubb
- id: bla
text: blubb
Item:
type: object
properties:
id:
type: string
name:
type: string
Swagger UI displays the request body example as follows:
and the request body schema as follows:
Why does it show an orderedmap instead of my normal objects?
Can someone tell me how to do the spec right for having the array with items correct?
Examples inside schemas use the example keyword (singular), not examples (plural).
Also, your YAML indentation is wrong - Items and Item must be indented under schemas, list items in the example must have the same indent, etc. If you paste your spec into http://editor.swagger.io, it will point out syntax errors.
Here's the fixed version:
components:
schemas:
Items:
type: array
items:
$ref: '#/components/schemas/Item'
example: # <------
- id: bla
text: blubb
- id: bla
text: blubb
Item:
type: object
properties:
id:
type: string
name:
type: string
Moreover, you get an example as 'orderedmap' because the example field is A free-form property.
But represent examples that cannot be naturally represented in JSON or YAML, a string value can be used to contain the example with escaping where necessary. (OpenAPI spec)
We can write an example as 'string' in both ways:
1.
example: '[ currency: USD, amount: 123 ]'
example: |
[
currency: USD,
amount: 123
]

OpenAPI reuse part of definition without defining a new one

Suppose that I have this definition in a yaml OpenApi definition
definitions:
User:
description: "User"
type: "object"
properties:
firstname:
type: "string"
lastname:
type: "string"
password:
type: "string"
email:
type: "string"
username:
type: "string"
If in a parameters specification I need specific fields of a definition how can I refer them without defining another model as below?
definitions:
UserLogin:
description: "User"
type: "object"
properties:
password:
type: "string"
email:
type: "string"
In your question, you are using definitions keyword what hints that your question is about OpenAPI v2 aka. Swagger. For OpenAPI v3, definitions provided below should be defined inside appropriate Components Object sections.
In order to achieve this, you have to use Composition with keyword allOf. There is a great example that relates to your question here. First, you have to define a smaller object and then include it into the definition of a larger as follows:
definitions:
UserLogin:
description: User Login
type: object
properties:
password:
type: string
email:
type: string
User:
allOf:
- $ref: '#/definitions/UserLogin'
- description: User
type: object
properties:
firstname:
type: string
lastname:
type: string
username:
type: string
It is worth noting that:
Some lighter implementations may not support allOf keyword.
Using composition may increase or decrease the readability of the documentation, depending on the complexity and choice of words used to name the schemas.

Creating an extendible model using Swagger/ OpenAPI

In my API i would like to have a simple model for my collection and a more elaborate model for my individual resource. For example:
a GET request on /libraries should return
BaseLibrary:
type: object
properties:
library_id:
type: string
description: The id of the library
display_name:
type: string
description: Name of the library
href:
type: string
description: The URI linking to this library.
whilst a request to a specific library should return all of the above including an extra parameter books:
So a GET request to libraries/{library_id} should return:
ExtendedLibrary:
type: object
properties:
library_id:
type: string
description: The id of the library
display_name:
type: string
description: Name of the library
href:
type: string
description: The URI linking to this library.
books:
type: array
description: The books in this library
items:
$ref: "#/definitions/books"
I would very much like to not have to define a "BaseLibrary" twice and would want to simple model an additional "ExtendedLibrary" which contains all the responses of a base library and the additional books property.
I tried a lot of different things, with the closest to succes being the following definitions:
definitions:
BaseLibrary:
type: object
properties:
library_id:
type: string
description: The id of the library.
display_name:
type: string
description: Name of the library
href:
type: string
description: The URI linking to this library.
ExtendedLibrary:
type: object
properties:
$ref: "#/definitions/BaseLibrary/properties"
books:
type: array
description: The available books for this library.
items:
$ref: "#/definitions/Book"
However this gives me a "Extra JSON reference properties will be ignored: books" warning and the output seems to ignore this extra property. Is there a clean way to handle my problem? Or am I just going to have to copy paste my whole BaseLibrary model into my ExtendedLibrary model?
As mentioned in the comments section, this may be a duplicate of another question, but it's worth repeating the answer in the context of this particular example. The solution is to use the allOf property in the definition of ExtendedLibrary:
definitions:
Book:
type: object
properties:
title:
type: string
author:
type: string
BaseLibrary:
type: object
properties:
library_id:
type: string
description: The id of the library
display_name:
type: string
description: Name of the library
href:
type: string
description: The URI linking to this library.
ExtendedLibrary:
type: object
allOf:
- $ref: '#/definitions/BaseLibrary'
- properties:
books:
type: array
description: The books in this library
items:
$ref: "#/definitions/Book"
In my experience, Swagger UI visualizes this correctly. When I define an operation response to be ExtendedLibrary Swagger UI shows this example:
{
"library_id": "string",
"display_name": "string",
"href": "string",
"books": [
{
"title": "string",
"author": "string"
}
]
}
Also, Swagger Codegen does the right thing. At least when generating a Java client, it creates an ExtendedLibrary class that correctly extends BaseLibrary.

How to declare a collection resource model in swagger 2.0?

I'm not sure about how I should do the declaration of the model for a collection resource on swagger.
The spec is missing some examples, so I'm guessing something like this:
Class:
required:
- id
- name
properties:
id:
type: string
name:
type: string
ClassList:
type: array
items:
type:
schema:
$ref: Class
Then swagger editor shows the following generated documentation:
Is it correct?
I think you got the answer to this one already, but even for the sake of documentation:
ClassList:
type: array
items:
$ref: #/definitions/Class

Resources