Swagger-ui problems trying to use a object parameter containing a array - swagger

Seem to almost have it...
Trying to have swagger send an anonymous hash of parameters in the request body.
I have an anonymous hash containing one key named list that contains an array.
Trying to send this parameter (text/json):
{
list : [ 'string1', 'string2' ]
}
Swagger is building the right curl statement but is not sending the parameters via the UI.
Swagger builds this (works from command line):
/usr/bin/curl -H 'Content-Type: text/json' -X GET -d '{ "list" : [ "text:/export/home/ihome/perl5/our_modules/check_parse_lib_rest/t/data/hosts:/export/home/ihome/perl5/our_modules/check_parse_lib_rest/t/data/hosts", "text:/export/home/ihome/perl5/our_modules/check_parse_lib_rest/t/data/hosts:/export/home/ihome/perl5/our_modules/check_parse_lib_rest/t/data/hosts.1" ] }' 'https://localhost.localdomain:9086/library/check_diff_batch'
But Swagger-ui shows no model example and sends no parameters in the request body.
In the editor I see it the list shows as undefined.
Schema
⇄
Comparison {
list:
ComparisonList undefined *
}
Definition -
paths:
/check_diff_batch:
get:
summary: Compare a list of file comparrison objects using diff.
description: |
FIXME: Takes an array of colon delimited comparrison objects.
Required parameter Comparrison object format = type:file1:file2
**RC** will return false if there are differences or a failure.
**FAULT_MSG** will return No Faults or a failure message.
parameters:
- $ref: "#/parameters/ComparrisonList"
responses:
200:
description: Successful response
examples:
text/json:
...
parameters:
ComparrisonList:
name: list
in: body
description: List of comparrison objects
schema:
$ref: "#/definitions/Comparisons"
definitions:
Comparisons:
required:
- list
properties:
list:
$ref: "#/definitions/ComparisonList"
ComparisonList:
additionalProperties:
type: string

additionalProperties is used to define associative arrays / hashmaps, not regular arrays. A regular string array is defined as:
definitions:
ComparisonList:
type: array
items:
type: string
You should also use a post operation and not get, since request body in GET does not have defined semantics as per RFC 7231 section 4.3.1.

Related

Swagger: cannot set "collectionFormat"

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.)

How to serialize query object with custom delimeter

I have yaml file:
openapi: 3.0.1
info:
title: My API
version: v1
paths:
# /users;id=3;id=4?metadata=true
/users:
get:
parameters:
- in: query
name: offset
schema:
type: integer
description: The number of items to skip before starting to collect the result set
- in: query
name: limit
schema:
type: integer
description: The numbers of items to return
- in: query
name: origin
style: form
explode: false
schema:
type: object
properties:
city:
type: string
zip:
type: string
responses:
'200':
description: A list of users
When I click "execute" in https://editor.swagger.io, the generated Curl looks like this:
curl -X GET "https://editor.swagger.io/users?offset=2&limit=12&origin=city,atlanta,zip,303" -H "accept: */*"
However, I need it to be like this:
curl -X GET "https://editor.swagger.io/users?offset=2&limit=12&origin=city:atlanta|zip:303" -H "accept: */*"
Is it possible to do this? I could not find any info in documentation about setting custom delimeters.
Short answer: No.
Your specific use case isn't covered by serialize parameters and they follow the rfc6570 - it's a good idea to follow the standard if you want to design a well accepted web api.
You specified explode: false and style:form.
When you turn explode:true on you will get this instead:
city=atlanta&zip=303
When you specify style:deepObject you will get:
origin[city]=atlanta&origin[zip]=303
The spaceDelimited and pipeDelimited style won't work with objects.
Working without schema
You can of cause work without a schema and define your origin query parameter of type string.
The documentation should explain exactly what you expect and a little example will help people to use your API.
I won't use that pattern for an open API, but this can be a workaround for an internal API.

Swagger 2: use enum reference in query parameter of array type

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:

How to define different query parameters for same path in OpenAPI (Swagger)?

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

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