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.)
Related
Let's say I've got a parameter like limit. This one gets used all over the place and it's a pain to have to change it everywhere if I need to update it:
parameters:
- name: limit
in: query
description: Limits the number of returned results
required: false
type: number
format: int32
Can I use $ref to define this elsewhere and make it reusable? I came across this ticket which suggests that someone wants to change or improve feature, but I can't tell if it already exists today or not?
This feature already exists in Swagger 2.0. The linked ticket talks about some specific mechanics of it which doesn't affect the functionality of this feature.
At the top level object (referred to as the Swagger Object), there's a parameters property where you can define reusable parameters. You can give the parameter any name, and refer to it from paths/specific operations. The top level parameters are just definitions and are not applied to all operations in the spec automatically.
You can find an example for it here - https://github.com/swagger-api/swagger-spec/blob/master/fixtures/v2.0/json/resources/reusableParameters.json - even with a limit parameter.
In your case, you'd want to do this:
# define a path with parameter reference
/path:
get:
parameters:
- $ref: "#/parameters/limitParam"
- $ref: "#/parameters/offsetParam"
# define reusable parameters:
parameters:
limitParam:
name: limit
in: query
description: Limits the number of returned results
required: false
type: integer
format: int32
offsetParam:
name: offset
in: query
description: Offset from which start returned results
required: false
type: integer
format: int32
For completeness, here's how it would look like in OpenAPI (a.k.a swagger v3):
openapi: "3.0.0"
servers:
- url: /v1
description: local server
paths:
/path:
get:
parameters:
- $ref: "#/components/parameters/limitParam"
components:
parameters:
limitParam:
name: limit
in: query
description: Limits the number of returned results
required: false
schema:
type: integer
minimum: 10
default: 10
multipleOf: 10 # matches 10, 20, ...
format: int32
I have an API with this URL:
/api/doSomething?key=value1=value2
Can this be represented in Swagger/OpenAPI 3.0? And if so, how would that look like? Without the second value2 I would specify it like this:
/api/doSomething:
get:
summary: ''
parameters:
- in: path
name: key
description: ''
required: true
schema:
type: string
OpenAPI supports the following array value separators in the query string: , | %20. OpenAPI 2.0 also supports \t.
= is NOT supported as a separator for array values.
The most you can do is document your key parameter as type: string and explain the format in the description. Assuming you use openapi: 3.0.0:
parameters:
- in: query
name: filter
required: true
schema:
type: string
description: A list of values separated by `=`.
example: value1=value2
Also note that = is a reserved character. In OpenAPI 3.0, query parameters have the additional allowReserved attribute that controls whether reserved characters should be sent as-is or percent-encoded.
allowReserved: true
/api/doSomething?key=value1=value2
^
allowReserved: false
/api/doSomething?key=value1%3Dvalue2
^
The Parameter Object may contain a allowReserved option that allows the use of reserved characters like = in the parameter value. Does the following work for you?
/api/doSomething:
get:
summary: ''
parameters:
- in: path
name: key
description: ''
required: true
allowReserved: true
schema:
type: string
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
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.