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
]
Related
I am trying to define my API using OpenAPI version 3.0. I am trying to generate a YAML file which has four maps, and each map contains a different information. How can I create a YAML file to achieve that goal? I know that my components are not right because of which I am not getting the right result.
Request body should be like this:
[
UserInformation{FirstName, LastName},
AddressInformation{Phone, Address},
ContactInformation{Email, Phone}
]
openapi: 3.0.0
info:
version: 1.0.0
title: 'INPUT-FORM-API'
paths:
/api/v1/test/healthcheck:
get:
summary: Health check for the test api services. Used Internally
operationId: Externalhealthcheck
description: healthcheck for the test services status.
responses:
'200':
description: This status is always returned when service is Ok.
content:
application/json:
schema:
$ref: '#/components/schemas/HealthcheckObject'
/api/v1/test/newformentry:
post:
summary: End Point to insert data into the new table.
operationId: NewFormEntry
description: EndPoint to insert data for new form.
requestBody:
content:
application/json:
schema:
items:
$ref: '#/components/schemas/NewFormEntry'
responses:
'200':
description: This status is always returned when service is Ok.
content:
application/json:
schema:
$ref: '#/components/schemas/HealthcheckObject'
components:
schemas:
NewFormEntry:
$ref: '#/components/schemas/UserInformation'
$ref: '#/components/schemas/AddressInformation'
$ref: '#/components/schemas/ContactInformation'
$ref: '#/components/schemas/MessageFromBene'
UserInformation:
required:
- FirstName
- LastName
properties:
FirstName:
type: string
LastName:
type: string
AddressInformation:
required:
- StreetAddress
- City
- State
- ZipCode
properties:
StreetAddress:
type: string
StreetAddress2:
type: string
City:
type: string
State:
type: string
ZipCode:
type: integer
format: int64
ContactInformation:
required:
- PhoneNumber
- Email
properties:
PhoneNumber:
type: integer
format: int64
maximum: 9
Email:
type: string
HomePhone:
type: integer
format: int64
maximum: 9
Cell:
type: integer
format: int64
maximum: 9
WorkPhone:
type: integer
format: int64
maximum: 9
MessageFromBene:
required:
- Message
properties:
PhoneNumber:
type: integer
format: int64
maximum: 9
Message:
type: string
HealthcheckObject:
required:
- Status
- ErrorMessage
properties:
Status:
type: string
ErrorMessage:
type: string
So the NewFormEntry schema must be an array containing 3 objects, where the 1st object must be UserInformation, the second object must be AddressInformation, and the 3rd object mube be ContactInformation. This is like a tuple, i.e. an ordered sequence of elements where each element has a specfic type. Tuple definitions are slightly different in different OpenAPI versions.
OpenAPI 3.1
If or when you migrate to OAS 3.1, such an array can be defined using prefixItems. This keyword specifies the schema for each element position (in other words, it specifies the order of elements in the array):
components:
schemas:
NewFormEntry:
type: array
prefixItems:
- $ref: '#/components/schemas/UserInformation' # type of the 1st element
- $ref: '#/components/schemas/AddressInformation' # type of the 2nd element
- $ref: '#/components/schemas/ContactInformation' # type of the 3rd element
minItems: 3
maxItems: 3
additionalItems: false # can be omitted if `maxItems: 3` is specified
OpenAPI 3.0
In OAS 3.0, you can define the array length (i.e. 3 items) and the possible types of array items (i.e. each item can be either A, B, or C), but there's no way to define a specific order of objects in the array. So the most you can do is this:
components:
schemas:
NewFormEntry:
type: array
items:
oneOf:
- $ref: '#/components/schemas/UserInformation'
- $ref: '#/components/schemas/AddressInformation'
- $ref: '#/components/schemas/ContactInformation'
minItems: 3
maxItems: 3
Note that this definition allows arbitrary order of objects in the array and also multiple instances of the same object (e.g. [UserInformation, UserInformation, UserInformation]). You might want to implement additional backend validations to verify the desired order of objects in this array.
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
]
}
I defined in swagger editor the following object(amountInCurrency):
pot:
type: object
properties:
potId:
type: string
name:
type: string
amount:
type: number
status:
type: string
lastChangeTimestamp:
type: string
amountInCurrency:
type: object
items:
$ref: '#/definitions/amountInCurrency'
and
amountInCurrency:
type: object
properties:
currency:
type: string
amount:
type: number
I got in that items currency and amount. however on swagger visualization i see amountInCurrency as an empty map. any idea why?
i would expect to see the currency and amount fields describe in it
-- edit:
if I change the AmountInCurrency type from object to array I do see the internal docs within the doc
doing this:
amountInCurrency:
type: array
items:
$ref: '#/definitions/amountInCurrency'
The amountInCurrency property definition does not look right - it mixes type: object with an array-specific keyword items.
If the amountInCurrency property is an array of amountInCurrency objects, use type: array instead:
amountInCurrency:
type: array # <-----
items:
$ref: '#/definitions/amountInCurrency'
If the amountInCurrency property is an object (an instance of the amountInCurrency object), use $ref like so:
amountInCurrency:
$ref: '#/definitions/amountInCurrency'
I have an object that has a property that is an object whose type would be one of list of types. All my attempts have been rejected by Swagger Editor with the following error:
Data does not match any schemas from 'anyOf'
Jump to line 43
Details
Object
code: "ANY_OF_MISSING"
message: "Data does not match any schemas from 'anyOf'"
path: Array [7]
inner: Array [2]
level: 900
type: "Swagger Error"
description: "Data does not match any schemas from 'anyOf'"
lineNumber: 43
The full swagger specification file is as follows (the field in question is DataSetsInquiryRsp.dataSets.dataSet):
swagger: '2.0'
info:
title: My API
description: My Awesome API
version: 1.0.0
paths:
/dataSetsInquiry:
get:
description: Retrieve one or more data-sets.
parameters:
- name: ids
in: query
description: List of identifiers of requested data-sets.
required: true
type: array
items:
type: string
responses:
'200':
description: Requested data-sets.
schema:
$ref: '#/definitions/DataSetsInquiryRsp'
default:
description: Unexpected error
schema:
$ref: '#/definitions/Error'
definitions:
DataSetsInquiryRsp:
type: object
additionalProperties: false
properties:
sessionIdentifier:
description: Identifier of the secure session with the server.
type: number
dataSets:
type: object
additionalProperties: false
properties:
id:
type: string
dataSet:
type: array
items:
oneOf:
- $ref: '#/definitions/Customer'
- $ref: '#/definitions/Merchant'
Customer:
type: object
additionalProperties: false
properties:
firstName:
description: First name of the customer
type: string
lastName:
description: Last name of the customer
type: string
Merchant:
type: object
additionalProperties: false
properties:
code:
description: Code the Merchant.
type: string
name:
description: Name of the Merchant.
type: string
Well, the issue is simply the fact that Swagger doesn't support oneOff. In fact, Swagger supports a subset of Json-Schema and add a few things (datatype file for instance).
What is bad here is the error returned by Swagger. It doesn't help match. And this is the case of all Json-Schema validators I have worked with so far: is-my-json-valid, jsen.
I'm trying to figure out how to use top level parameters and then, at the operation level,use a $ref to refer to the definition that was declared at the top level object.
Here is what the YAML looks like but when I try this I get an empty parameter displayed. Anyone know the correct syntax for this?
swagger: '2.0'
info:
version: 0.1.0
title: Customer API
parameters:
index:
name: index
in: query
description: Specifies the offset of the first item to be returned. The default value is 0, which starts at the beginning.
type: integer
default: 0
minimum: 0
paths:
/customers:
get:
parameters:
- $ref: '#/parameters/index'
responses:
200:
description: List all customers
schema:
$ref: '#/definitions/Customers'
definitions:
Customer:
properties:
name:
type: string
id:
type: integer
format: int32
Customers:
properties:
startIndex:
type: integer
itemsPerPage:
type: integer
totalResults:
type: integer
entries:
type: array
$ref: Customer
The support for this has yet to be implemented in swagger-ui. See https://github.com/swagger-api/swagger-ui/issues/621.