I have an endpoint with query parameters that use square brackets:
GET /info?sort[name]=1&sort[age]=-1
Here, name and age are the field names from my model definition.
How can I write an OpenAPI (Swagger) definition for these parameters?
It depends on which version of OpenAPI (Swagger) you use.
OpenAPI 3.x
The sort parameter can be defined an an object with the name and age properties. The parameter serialization method should be style: deepObject and explode: true.
openapi: 3.0.0
...
paths:
/info:
get:
parameters:
- in: query
name: sort
schema:
type: object
properties:
name:
type: integer
example: 1
age:
type: integer
example: -1
style: deepObject
explode: true
responses:
'200':
description: OK
This is supported in Swagger UI 3.15.0+ and Swagger-Editor 3.5.6+.
Important: The deepObject serialization style only supports simple non-nested objects with primitive properties, such as in the example above. The behavior for nested objects and arrays of objects is not defined.
In other words, while we can define
?param[foo]=...¶m[bar]=...
there's currently no way to define more nested query parameters such as
?param[0][foo]=...¶m[1][bar]=...
or
?param[foo][0][smth]=...&?param[foo][1][smth]=
If you need the syntax for deeply nested query parameters, upvote and follow this feature request:
Support deep objects for query parameters with deepObject style
OpenAPI 2.0 (Swagger 2.0)
sort[name] and sort[age] need to be defined as individual parameters:
swagger: '2.0'
...
paths:
/info:
get:
parameters:
- in: query
name: sort[name]
type: integer
- in: query
name: sort[age]
type: integer
responses:
200:
description: OK
Related
A JSON query should be usable with multiple search parameters. For this, the server needs to get each parameter as search object, for example:
url/search=FirstParameter[EQ]foo&search=SecondParameter[EQ]bar
We use the following declaration in swagger:
parameters:
searchParam:
description: |
array of strings like e.g. person.nameLast[\<operand>]Bur<br>
\<operands> \:= LEQ, LT, EQ, GT, GEQ, LIKE
name: search
in: query
schema:
type: array
writeOnly: true
items:
minItems: 1
type: string
The issue is, that the PHP library generated from swagger creates requests like this:
url/search=FirstParameter[EQ]foo&SecondParameter[EQ]bar
Which is not usable by server. To address this issue, i found that you could influence this behavior by setting the attribute "collectionFormat" not to multi but to csv.
My issue is, that declarations taken from the example page
https://swagger.io/docs/specification/2-0/describing-parameters/
do not work and display error:
should NOT have additional properties additionalProperty: collectionFormat
I've tried:
parameters:
searchParam:
description: |
array of strings like e.g. person.nameLast[\<operand>]Bur<br>
\<operands> \:= LEQ, LT, EQ, GT, GEQ, LIKE
name: search
in: query
schema:
type: array
collectionFormat: csv
writeOnly: true
items:
minItems: 1
type: string
What could be the issue?
collectionFormat is an OpenAPI 2.0 keyword (i.e. used in swagger: "2.0"), but you seem to be using OpenAPI 3.0 (openapi: 3.0.x). The corresponding OAS3 keywords are style and explode, see the Parameter Serialization guide for details.
Try the following:
paths:
/url:
get:
parameters:
- in: query
name: search
description: |-
An array of strings like e.g. `person.nameLast[<operand>]value`
<operand> can be: LEQ, LT, EQ, GT, GEQ, LIKE
schema:
type: array
minItems: 1 # This keyword must be on the same level as `type: array`
items:
type: string
# Optional example
example:
- FirstParameter[EQ]foo
- SecondParameter[EQ]bar
# This is the default serialization style for query parameters
# so you can omit these keywords if you wish
style: form
explode: true
Note that the requests will be sent with the [ and ] characters percent-encoded as %5B and %5D, because they are reserved characters according to RFC 3986.
url?search=FirstParameter%5BEQ%5Dfoo
The backend server is supposed to decode %5B...%5D back to [...]. (Any RFC-compliant server should do this automatically.)
I have a swagger 2.0 resource defined below. How can I make "param1 or param2" required? Caller has to pass either param1 or param2.
/some/res:
put:
summary: some resource
responses:
200:
description: Successful response
schema:
$ref: '#/definitions/SomeResponse'
parameters:
- name: param1
type: string
description: param1
in: formData
required: false
- name: param2
type: string
description: param2
in: formData
required: false
OpenAPI (fka Swagger) Specification does not support conditional or mutually exclusive parameters (of any type).
There is an open feature request:
Support interdependencies between query parameters
The specific scenario in this question – a POST/PUT/PATCH request with a form-data body that contains either param1 or param2 – can be defined using OpenAPI 3.0 and oneOf:
openapi: 3.0.0
...
paths:
/some/res:
put:
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema:
oneOf:
- type: object
properties:
param1:
type: string
required:
- param1
additionalProperties: false
- type: object
properties:
param2:
type: string
required:
- param2
additionalProperties: false
Note for Swagger UI users: form-data UI and example rendering for oneOf schemas are not available for OpenAPI 3.0 definitions yet.
In the Parameter Dependencies section of the Describing Parameters Swagger docs:
Swagger does not support parameter dependencies and mutually exclusive parameters. There is an open feature request at https://github.com/OAI/OpenAPI-Specification/issues/256.
As of June 2017, that issue had 21 upvotes, making it the third most upvoted issue in the project.
The Swagger specification does not support conditional requirement or inclusion/exclusion of parameters.
What I would suggest is to state clearly in the description your rules for inclusion/exclusion of query parameters. Then using a validation framework, which depends on your language (i.e. javax.validation for Java, restify-validation for restify, etc.), validate the parameters accordingly.
You can use a simple trick. Use different requests with the same route but define different "home made" query parameters using "path" type instead of the "query".
For some interdependent logic between parameters, put the logic in your API and define specific responses based on correct/uncorrect requests. You can also protect the URL definition on the client-side, but let the stuff where they belong.
/myUrl/myRoute/?queryPara1={query1}?queryPara2={query2}:
get:
parameters:
- in: path
name: query1
schema:
type: string
- in: path
name: query2
schema:
type: string
/myUrl/myRoute/?queryPara3={query3}?queryPara4={query4}:
get:
parameters:
- in: path
name: query3
schema:
type: string
- in: path
name: query4
schema:
type: string
Can not get how to use reference of string type with enum values in array parameter.
I can make reference in items key and it is working, but Swagger produce error: Not a valid parameter definition
Web UI generates interface, but it have textarea instead of multiselect box I expected.
What is the proper way to do it?
My code:
swagger: '2.0':
paths:
/test:
get:
parameters:
- in: origin
name: status
description: Origin
required: false
schema:
type: array
items:
$ref: '#/definitions/Origin'
collectionFormat: pipes'
definitions:
Origin:
type: string
description: Campaign origin
enum:
- one
- two
externalDocs:
description: Find out more about Swagger
url: http://swagger.io
host: virtserver.swaggerhub.com
basePath: /
Array parameters with items containing $ref are not supported in OpenAPI/Swagger 2.0. But it looks like this will be possible in the next version, 3.0. For now there are a couple of workarounds, see below.
Your spec also has some other issues:
in: origin is not valid. The in keyword specifies the parameter location (path, query, header, etc.) and only accepts certain values as per the OpenAPI/Swagger spec. I guess you meant in: query or in: header.
Typos (or copy-paste errors?): swagger: '2.0': has an extra : at the end and collectionFormat: pipes' has an extra ' at the end.
One solution for having an array parameter containing enum values is to define the enum inline:
parameters:
- in: query
name: status
description: Origin
required: false
type: array
collectionFormat: pipes
items:
type: string
enum:
- one
- two
Another solution (found here) is to use YAML anchors to reference the enum. This is a feature of YAML where you can mark a key with &anchor-name and then further down use *anchor-name to reference that key's value.
definitions:
Origin:
type: string
description: Campaign origin
enum: &origin
- one
- two
paths:
/test:
get:
parameters:
- in: query
name: status
description: Origin
required: false
type: array
collectionFormat: pipes
items:
type: string
enum: *origin
One option is to define a parameter and make a reference to that: (I had an issue with using reference ($ref:) within a query definition)
paths:
/path:
get:
operationId: controllers.controller
parameters:
**- $ref: '#/parameters/SPEC'**
parameters:
SPEC:
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.
I have a swagger 2.0 resource defined below. How can I make "param1 or param2" required? Caller has to pass either param1 or param2.
/some/res:
put:
summary: some resource
responses:
200:
description: Successful response
schema:
$ref: '#/definitions/SomeResponse'
parameters:
- name: param1
type: string
description: param1
in: formData
required: false
- name: param2
type: string
description: param2
in: formData
required: false
OpenAPI (fka Swagger) Specification does not support conditional or mutually exclusive parameters (of any type).
There is an open feature request:
Support interdependencies between query parameters
The specific scenario in this question – a POST/PUT/PATCH request with a form-data body that contains either param1 or param2 – can be defined using OpenAPI 3.0 and oneOf:
openapi: 3.0.0
...
paths:
/some/res:
put:
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema:
oneOf:
- type: object
properties:
param1:
type: string
required:
- param1
additionalProperties: false
- type: object
properties:
param2:
type: string
required:
- param2
additionalProperties: false
Note for Swagger UI users: form-data UI and example rendering for oneOf schemas are not available for OpenAPI 3.0 definitions yet.
In the Parameter Dependencies section of the Describing Parameters Swagger docs:
Swagger does not support parameter dependencies and mutually exclusive parameters. There is an open feature request at https://github.com/OAI/OpenAPI-Specification/issues/256.
As of June 2017, that issue had 21 upvotes, making it the third most upvoted issue in the project.
The Swagger specification does not support conditional requirement or inclusion/exclusion of parameters.
What I would suggest is to state clearly in the description your rules for inclusion/exclusion of query parameters. Then using a validation framework, which depends on your language (i.e. javax.validation for Java, restify-validation for restify, etc.), validate the parameters accordingly.
You can use a simple trick. Use different requests with the same route but define different "home made" query parameters using "path" type instead of the "query".
For some interdependent logic between parameters, put the logic in your API and define specific responses based on correct/uncorrect requests. You can also protect the URL definition on the client-side, but let the stuff where they belong.
/myUrl/myRoute/?queryPara1={query1}?queryPara2={query2}:
get:
parameters:
- in: path
name: query1
schema:
type: string
- in: path
name: query2
schema:
type: string
/myUrl/myRoute/?queryPara3={query3}?queryPara4={query4}:
get:
parameters:
- in: path
name: query3
schema:
type: string
- in: path
name: query4
schema:
type: string