OpenApi 3.0 one or more field requiered - swagger

Body
{
"param1": "string", #required or
"param2": "string", #required or
"param3": "string", #required
"param4": true,
"param5": "string"
}
one or more params are required.
which is yaml sintax for define parm1 or parm2 or parm3 required?
thx.

Does restricting the number of object property count with "minProperties": 3 work for you? If it doesn't fit you, then you will need very complicated if-then-else structures to express this (in which case it is just better to implement this check with programmatic validation, rather than in the json schema).

Assuming you use OpenAPI 3.x, you need a combination of anyOf + required:
type: object
anyOf:
- required: [param1]
- required: [param2]
- required: [param3]
properties:
...
This syntax means: at least param1 or param2 or param3 (or any combination of these properties) must be present.

Related

requestBody not displaying subtypes with arrays within a $ref component but shows correctly in response body

I've been struggling with an issue in an openapi 3.0.1 spec json document I've been working on.
The issue I'm seeing in the online swagger editor (editor.swagger.io) is very strange where the Request body Example Value section of a POST does not show the "layers", which is an array defined within my MixBase schema component, based on the MixLayer schema component. The MixLayer schema component has an array of MixLayerComponent schema components.
However, if I include a $ref to the MixBase schema in the responses section, all the elements are shown correctly.
Request body Example Value section that is missing the 'layers':
{
"mixId": "4f8b533f-7449-4056-92ff-11b1de94d656",
"mixDescription": "SES5M",
"mixScaleName": "MyScale",
"mixRoom": "MixingRoomABC",
"mixProgramId": "ABC-123-ProgramId",
"mixDateTime": "2018-06-07T12:51:25.077Z",
"mixState": "Paused",
"mixNumber": "131",
"mixedByUserName": "john.smith#example.com",
"mixedByFirstName": "John",
"mixedByLastName": "Smith"
}
Responses Example Value section returning the correct list of elements including 'layers':
{
"mixId": "4f8b533f-7449-4056-92ff-11b1de94d656",
"mixDescription": "SES5M",
"mixScaleName": "MyScale",
"mixRoom": "MixingRoomABC",
"mixProgramId": "ABC-123-ProgramId",
"mixDateTime": "2018-06-07T12:51:25.077Z",
"mixState": "Paused",
"mixNumber": "131",
"mixedByUserName": "john.smith#example.com",
"mixedByFirstName": "John",
"mixedByLastName": "Smith",
"layers": [ -- this represents the MixLayer component
{
"unitOfMeasure": "g",
"Components": [ -- this represents the MixLayerComponent correctly
{
"code": "800C",
"description": "800C",
"poured": 204.5,
"density": 1.041
}
]
}
]
}
My requestBody section is defined as: (doesn't show 'layers')
requestBody:
required: true
description: Paint mix information to create
content:
application/json:
schema:
$ref: '#/components/schemas/MixBase'
My responses section is defined as: (and this displays correctly in the Response examples section)
responses:
'200':
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/MixBase'
Here is the definition of the 'layers' within the MixBase schema component (which is the last element in the MixBase definition which is why additionalProperties is set to false): (The formatting might not be correct in stack overflow but the swagger editor doesn't complain so I don't believe the issue is linked to formatting)
layers:
description: Layer related information for components of the mix
type: array
items:
$ref: '#/components/schemas/MixLayer'
readOnly: true
additionalProperties: false
Here is the definition of the MixLayer:
MixLayer:
required:
- Components
type: object
properties:
unitOfMeasure:
description: Unit of volume for the components of the layer
maxLength: 10
type: string
nullable: true
example: g
Components:
description: The components that make up the layer in the mix
type: array
items:
$ref: '#/components/schemas/MixLayerComponent'
readOnly: true
additionalProperties: false
Here is the definition of the MixLayerComponent:
MixLayerComponent:
required:
- code
- density
- poured
type: object
properties:
code:
description: The code associated with the mix component of the layer
maxLength: 25
minLength: 1
type: string
example: 800C
description:
description: The description of the mix component of the layer
maxLength: 120
type: string
nullable: true
example: 800C
poured:
description: >-
The quantity, expressed in the unit of measurement, consumed for the
mix component
type: number
format: double
example: 204.5
density:
description: The density associated with the mix component of the layer
type: number
format: double
example: 1.041
additionalProperties: false
I thought that the "Components" element in the MixLayer component schema might be a reserved keyword in openapi so I changed the references to something else and it still has the same issue.
I thought this issue might be with the online swagger editor (editor.swagger.io) but the same thing occurs in Postman. I also tried browsers Chrome, Edge, and Firefox and they all
have the same issue. I have also tried an XML content type in addition to the JSON I would like to use but still the same issue.
I don't access to post my openapi.json file on stack overflow but I hope this provides enough information.
Any insights anyone has for me to continue a line of investigation would be greatly appreciated.
Thank you for your time in advance,
Dave
layers is defined as a read-only property (readOnly: true) - that's why it doesn't appear in the request body example.

Why did a schema inherit examples of array items from its subschema?

OpenAPI 3.0.0, Swagger online editor.
I composed subschemas via the allOf discriminator and set the example field for a resulting schema. Swagger UI, however, didn't provide the example as-is.
The schema contained an array originating from the subschema. The array inherited example items from the subschema and extended the list with the examples from the schema.
Example
Let's say we have two schemas:
Cats:
type: object
properties:
cats:
type: array
items:
type: object
properties:
fluffiness:
type: integer
names:
type: string
example:
cats:
- fluffiness: 9
names: "Felix"
- fluffiness: 10
names: "Neko"
FluffiestCats:
allOf:
- $ref: '#/components/schemas/Cats'
- type: object
properties:
date:
type: string
format: "date"
example:
cats:
- fluffiness: 10
names: "Luna"
- fluffiness: 10
names: "Meowie"
date: "17-01-2021"
Responding to some request, the API retrieves the fluffiest cats, referencing #/components/schemas/FluffiestCats/. Swagger UI generates the following response example.
{
"cats": [
{
"fluffiness": 9,
"names": "Felix"
},
{
"fluffiness": 10,
"names": "Neko"
},
{
"fluffiness": 10,
"names": "Luna"
},
{
"fluffiness": 10,
"names": "Meowie"
}
],
"date": "17-01-2021"
}
Swagger UI takes two examples from the subschema example items. The provided example doesn't override the subschema example.
Does this behaviour contradict the specification? According to the description, it seems the Schema Object's example field doesn't imply override, in contrast to the Parameter Object's example field.
How can I override the subschema example? Or do I have to recreate the schema without using the allOf?
References
How to reference array item examples in OpenAPI 3?
OpenAPI 3.0.0 specification
It was an issue with Swagger UI.
Fixed in Swagger UI 4.5.0 and Swagger Editor 4.0.7.

How to have multiple data types for form body with swagger in aspnet core mvc?

Currently my swagger output as a body parameter that looks like this
{
"name": "body",
"in": "body",
"description": "",
"required": true,
"type": "file"
}
and i read the documentation that the type property can be a array of types
{
"name": "body",
"in": "body",
"description": "",
"required": true,
"type": [null,"file"]
}
but I have found no way to tell aspnet core mvc or swaggerGen to output two types? Is this possible.
I would like the swaggerUI to include the option to either select a file or post some json data. Can this be done?
and i read the documentation that the type property can be a array of types
"type": [null,"file"]
This is not valid in OpenAPI/Swagger. type must be a single type, and there's no null type.
I would like the swaggerUI to include the option to either select a file or post some json data.
In OpenAPI/Swagger 2.0 this is not possible – an operation can post either a file or JSON but not both. You'll need two operations - one that accepts JSON, and another one that accepts a file.
What you want will be possible using OpenAPI 3.0. However, I don't know if ASP.NET Core MVC supports OpenAPI 3.0; it may take some time before tools adopt the new version of OpenAPI.
Your API spec (in YAML) would look like this:
paths:
/something:
post:
requestBody:
description: Either a file or JSON object
required: true
content:
application/json:
schema:
type: object:
properties:
...
# Post a file via a multipart request
multipart/form-data:
schema:
type: object
properties:
file: # <-- here "file" is a form field name
type: string
format: binary
required:
- file
# or maybe...
# Post a file directly
application/octet-stream:
schema:
type: string
format: binary
responses:
...

How to specify a property can be null or a reference with swagger

How to specify a property as null or a reference? discusses how to specify a property as null or a reference using jsonschema.
I'm looking to do the same thing with swagger.
To recap the answer to the above, with jsonschema, one could do this:
{
"definitions": {
"Foo": {
# some complex object
}
},
"type": "object",
"properties": {
"foo": {
"oneOf": [
{"$ref": "#/definitions/Foo"},
{"type": "null"}
]
}
}
}
The key point to the answer was the use of oneOf.
The key points to my question:
I have a complex object which I want to keep DRY so I put it in a
definitions section for reuse throughout my swagger spec: values of other properties; response objects, etc.
In various places in my spec a
property may be a reference to such an object OR be null.
How do I specify this with Swagger which doesn't support oneOf or
anyOf?
Note: some swagger implementations use x-nullable (or some-such) to specify a property value can be null, however, $ref replaces the object with what it references, so it would appear any use of x-nullable is ignored.
OpenAPI 3.1
Define the property as anyOf of the $ref and type: 'null'.
YAML version:
foo:
anyOf:
- type: 'null' # Note the quotes around 'null'
- $ref: '#/components/schemas/Foo'
JSON version:
"foo": {
"anyOf": [
{ "type": "null" },
{ "$ref": "#/components/schemas/Foo" }
]
}
Why use anyOf and not oneOf? oneOf will fail validation if the referenced schema itself allows nulls, whereas anyOf will work.
OpenAPI 3.0
YAML version:
foo:
nullable: true
allOf:
- $ref: '#/components/schemas/Foo'
JSON version:
"foo": {
"nullable": true,
"allOf": [
{ "$ref": "#/components/schemas/Foo" }
]
}
In OAS 3.0, wrapping $ref into allOf is needed to combine the $ref with other keywords - because $ref overwrites any sibling keywords. This is further discussed in the OpenAPI Specification repository: Reference objects don't combine well with “nullable”
Not easy to do that. Even almost impossible. Your options :
Wait
There is a very long discussion about this point, maybe one day it will be done...
Use vendors extensions
You can use vendors extensions like x-oneOf and x-anyOf. I have already taken this hard way: You must to upgrade all used 'swagger tools' to take into account these vendors extensions.
In my case, we needed 'only' to :
Develops our own Jax-RS parser with customized annotations in order to extract swagger API file from sources
Extends swagger-codegen to take into account these extensions to generate java code for our clients
Develops our own swagger-ui: to facilitate this work, we added a preprocessing step to convert our swagger schema with our extensions to a valid json schema. It's easier to find a module to represent json schemas than swagger schemas in javascript. By cons we gave up the idea to test the API with the 'try it' button.
It was a year ago, maybe now ...
Refactor your APIs
Many projects don't need anyOf and oneOf, why not us ?
For OpenAPI 3.0 for some reason using nullable: true followed by allOf didn't work for the OpenAPI interpreter I'm using. As a workaround I ended up defining a must-be-null ref called null_type that I can use in an anyOf construct.
Like so:
allOf:
- anyOf:
- $ref: "#/components/schemas/null_type"
- $ref: "#/components/schemas/your_ref"
- description: "optionally add other properties here..."
where:
schemas:
null_type:
title: "OpenAPI 3.0 null-type ref"
description: "for adding nullability to a ref"
enum: [null]
your_ref:
...

Use object type query param in swagger documentation

I have a GET route where I would like to encode an object parameter in the url as a query string.
When writing the swagger documentation I basically get errors that disallow me to use schema/object types in a query type parameter:
paths:
/mypath/:
get:
parameters
- in: path
name: someParam
description: some param that works
required: true
type: string
format: timeuuid #good param, works well
- $ref: "#/parameters/mySortingParam" #this yields an error
parameters:
mySortingParam
name: paging
in: query
description: Holds various paging attributes
required: false
schema:
type: object
properties:
pageSize:
type: number
cursor:
type: object
properties:
after:
type: string
format: string
The request query param having an object value would be encoded in an actual request.
Even though swagger shows an error at the top of the screen the object is rendered correctly in the swagger UI editor, however with that error floating on top of the documentation.
I don't think you can use "object" as query parameter in Swagger spec as query parameter only supports primitive type (https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#data-types)
This is now possible with OpenAPI 3.0.
parameters:
- in: query
name: values
schema:
type: object
properties:
genre_id:
type: integer
author_id:
type: integer
title:
type: string
example:
{
"genre_id": 1,
"author_id": 1
}
style: form
explode: true
Here you can use style and explode keywords to specify how parameters should be serialised.
style defines how multiple values are delimited. Possible styles depend on the parameter location – path, query, header or cookie.
explode (true/false) specifies whether arrays and objects should
generate separate parameters for each array item or object property.
For the above example the url will be:
https://ebookstore.build/v1/users/books/search?genre_id=1&author_id=1
For more information on describing parameters with OpenAPI v3 and parameter serialisation, please refer here.
This is possible, just not with OpenAPI 2.0. OpenAPI 3.0 describes how this is possible here:
https://swagger.io/docs/specification/describing-parameters/
parameters:
- in: query
name: filter
# Wrap 'schema' into 'content.<media-type>'
content:
application/json: # <---- media type indicates how to serialize / deserialize the parameter content
schema:
type: object
properties:
type:
type: string
color:
type: string
In the meantime you could just have the query parameter as a plain old string type and then perform the serialization manually, then set the query parameter as required. This is what I'm doing until Swagger UI fully supports OpenAPI 3.0.

Resources