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
Related
I am starting a REST service, using Swagger Codegen. I need to have different responses for different parameters.
Example: <baseURL>/path can use ?filter1= or ?filter2=, and these parameters should produce different response messages.
I want my OpenAPI YAML file to document these two query params separately. Is this possible?
It is not supported in the 2.0 spec, and not in 3.0 either.
Here are the corresponding proposals in the OpenAPI Specification repository:
Accommodate legacy APIs by allowing query parameters in the path
Querystring in Path Specification
If you're still looking, I found out a way around this problem. It's a bit of a hack, but it works.
Basically, you can have two definitions to the same path by adding a slash (/) in the URL.
That way, you can set a response for <baseURL>/path with the ?filter1= parameter and set another response for <baseURL>//path with the ?filter2= parameter. It's also important that you give an unique operationId for each of the definitions.
paths:
/path/you/want:
get:
summary: Test
operationId: get1
parameters:
- name: filter1
type: string
in: path
required: true
responses:
200:
description: Successful response
schema:
$ref: '#/definitions/SomeResponse'
/path/you//want:
get:
summary: Another test
operationId: get2
parameters:
- name: filter2
type: string
in: path
required: true
responses:
200:
description: Successful response
schema:
$ref: '#/definitions/SomeOtherResponse'
I tried this with a path parameter and it worked just fine!
In swagger defining location,type explicitly is what defines these variables.
You have all the required fields to avoid collision of variables, for a json body you have to reference a declaration or use an example schema as shown below. For my case I have used a schema example rather than a declaration reference
/auth/account/password/reset/{userId}/{resetToken}:
post:
consumes:
- application/json
parameters:
- in: path
name: userId
type: string
required: true
- in: path
type: string
name: resetToken
required: true
- in: header
name: authorization
required: true
type: string
- in: body
name: body
required: true
schema:
type: object
example:
password: password
confirmPassword: password
responses:
"200":
description: OK
In Swagger you can add ? to make endpoints different.
i.e. /articles and /articles?:
When using ? in Swagger editor you will see error:
However on your final Swagger page there will be mark VALID
Additional information:
Remember about unique operationId for duplicated entries
# GET verb version of the "GetClientsForGadget" method from the original ASMX Service
/clients/ProspectClient/roleandcstbased/{OrgNmFilter}/{SortNm}?{UserName}:
get:
tags:
- Client
summary: Merging of GetClientsforGadget and GetClientsForUser
operationId: ClientsForGadgetGET
parameters:
- name: OrgNmFilter
in: path
description: Organization Name Filter
required: true
type: string
- name: SortNm
in: path
description: Sort Field
required: true
type: string
- name: UserName
in: query
description: User's Identity
required: false
type: string
responses:
200:
description: Output results for GetClientsForGadget endpoint
schema:
$ref: '#/definitions/ClientOutput'
Swagger is giving me not a valid parameter definition for this query parameter. If I remove all references to Username in the path and parameter definition, no issues.
According to the Swagger Specification, I believe I'm using query parameters right, but somehow it's not.
Realized the issue was in path. The path does not need to include the query parameter.
/clients/ProspectClient/roleandcstbased/{OrgNmFilter}/{SortNm}?{UserName}:
/clients/ProspectClient/roleandcstbased/{OrgNmFilter}/{SortNm}:
It only needs the query to be defined in parameters. Otherwise bugs the whole thing out.
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
I'm preparing my API documentation by doing it per hand and not auto generated. There I have headers that should be sent to all APIs and don't know if it is possible to define parameters globally for the whole API or not?
Some of these headers are static and some has to be set when call to API is made, but they are all the same in all APIs, I don't want to copy and paste parameters for each API and each method as this will not be maintainable in the future.
I saw the static headers by API definition but there is no single document for how somebody can set them or use them.
Is this possible at all or not?
It depends on what kind of parameters they are.
The examples below are in YAML (for readability), but you can use http://www.json2yaml.com to convert them to JSON.
Security-related parameters: Authorization header, API keys, etc.
Parameters used for authentication and authorization, such as the Authorization header, API key, pair of API keys, etc. should be defined as security schemes rather than parameters.
In your example, the X-ACCOUNT looks like an API key, so you can use:
swagger: "2.0"
...
securityDefinitions:
accountId:
type: apiKey
in: header
name: X-ACCOUNT
description: All requests must include the `X-ACCOUNT` header containing your account ID.
# Apply the "X-ACCOUNT" header globally to all paths and operations
security:
- accountId: []
or in OpenAPI 3.0:
openapi: 3.0.0
...
components:
securitySchemes:
accountId:
type: apiKey
in: header
name: X-ACCOUNT
description: All requests must include the `X-ACCOUNT` header containing your account ID.
# Apply the "X-ACCOUNT" header globally to all paths and operations
security:
- accountId: []
Tools may handle security schemes parameters differently than generic parameters. For example, Swagger UI won't list API keys among operation parameters; instead, it will display the "Authorize" button where your users can enter their API key.
Generic parameters: offset, limit, resource IDs, etc.
OpenAPI 2.0 and 3.0 do not have a concept of global parameters. There are existing feature requests:
Allow for responses and parameters shared across all endpoints
Group multiple parameter definitions for better maintainability
The most you can do is define these parameters in the global parameters section (in OpenAPI 2.0) or the components/parameters section (in OpenAPI 3.0) and then $ref all parameters explicitly in each operation. The drawback is that you need to duplicate the $refs in each operation.
swagger: "2.0"
...
paths:
/users:
get:
parameters:
- $ref: '#/parameters/offset'
- $ref: '#/parameters/limit'
...
/organizations:
get:
parameters:
- $ref: '#/parameters/offset'
- $ref: '#/parameters/limit'
...
parameters:
offset:
in: query
name: offset
type: integer
minimum: 0
limit:
in: query
name: limit
type: integer
minimum: 1
maximum: 50
To reduce code duplication somewhat, parameters that apply to all operations on a path can be defined on the path level rather than inside operations.
paths:
/foo:
# These parameters apply to both GET and POST
parameters:
- $ref: '#/parameters/some_param'
- $ref: '#/parameters/another_param'
get:
...
post:
...
If you're talking about header parameters sent by consumer when calling the API...
You can at least define them once and for all in parameters sections then only reference them when needed.
In the example below:
CommonPathParameterHeader, ReusableParameterHeader and AnotherReusableParameterHeader are defined once and for all in parameterson the root of the document and can be used in any parameters list
CommonPathParameterHeaderis referenced in parameters section of /resources and /other-resources paths, meaning that ALL operation of these paths need this header
ReusableParameterHeader is referenced in get /resources meaning that it's needed on this operation
Same thing for AnotherReusableParameterHeader in get /other-resources
Example:
swagger: '2.0'
info:
version: 1.0.0
title: Header API
description: A simple API to learn how you can define headers
parameters:
CommonPathParameterHeader:
name: COMMON-PARAMETER-HEADER
type: string
in: header
required: true
ReusableParameterHeader:
name: REUSABLE-PARAMETER-HEADER
type: string
in: header
required: true
AnotherReusableParameterHeader:
name: ANOTHER-REUSABLE-PARAMETER-HEADER
type: string
in: header
required: true
paths:
/resources:
parameters:
- $ref: '#/parameters/CommonPathParameterHeader'
get:
parameters:
- $ref: '#/parameters/ReusableParameterHeader'
responses:
'200':
description: gets some resources
/other-resources:
parameters:
- $ref: '#/parameters/CommonPathParameterHeader'
get:
parameters:
- $ref: '#/parameters/AnotherReusableParameterHeader'
responses:
'200':
description: gets some other resources
post:
responses:
'204':
description: Succesfully created.
If you're talking about header sent with each API response...
Unfortunately you cannot define reusable response headers.
But at least you can define a reusable response containing these headers for common HTTP responses such as a 500 error.
Example:
swagger: '2.0'
info:
version: 1.0.0
title: Header API
description: A simple API to learn how you can define headers
parameters:
CommonPathParameterHeader:
name: COMMON-PARAMETER-HEADER
type: string
in: header
required: true
ReusableParameterHeader:
name: REUSABLE-PARAMETER-HEADER
type: string
in: header
required: true
AnotherReusableParameterHeader:
name: ANOTHER-REUSABLE-PARAMETER-HEADER
type: string
in: header
required: true
paths:
/resources:
parameters:
- $ref: '#/parameters/CommonPathParameterHeader'
get:
parameters:
- $ref: '#/parameters/ReusableParameterHeader'
responses:
'200':
description: gets some resources
headers:
X-Rate-Limit-Remaining:
type: integer
X-Rate-Limit-Reset:
type: string
format: date-time
/other-resources:
parameters:
- $ref: '#/parameters/CommonPathParameterHeader'
get:
parameters:
- $ref: '#/parameters/AnotherReusableParameterHeader'
responses:
'200':
description: gets some other resources
headers:
X-Rate-Limit-Remaining:
type: integer
X-Rate-Limit-Reset:
type: string
format: date-time
post:
responses:
'204':
description: Succesfully created.
headers:
X-Rate-Limit-Remaining:
type: integer
X-Rate-Limit-Reset:
type: string
format: date-time
'500':
$ref: '#/responses/Standard500ErrorResponse'
responses:
Standard500ErrorResponse:
description: An unexpected error occured.
headers:
X-Rate-Limit-Remaining:
type: integer
X-Rate-Limit-Reset:
type: string
format: date-time
About OpenAPI (fka. Swagger) Next version
The OpenAPI spec (fka. Swagger) will evolve and include the definition of reusable response headers among other things (cf. https://github.com/OAI/OpenAPI-Specification/issues/563).
As per this Swagger issue comment, support for global parameters (including header parameters) is not planned in foreseeable future, but to limit the repetition you should use parameters references as in #Arnaud's answer (parameters: - $ref: '#/parameters/paramX').
also wish some global variables, can be used anywhere.
( even in some examples, so can change common settings globally in ui ).
something like
"hello ${var1}" in shell or javascript.
searched docs many times, not found solution yet.
: (