SwaggerUI 3 not respecting `explode: false` for query array parameters in OpenAPI 3 spec - swagger-ui

I have a query parameter defined in the OpenAPI 3 spec as follows:
parameters:
- in: query
name: categories
schema:
type: array
items:
type: string
enum:
- category1
- category2
style: form
explode: false
The expectation is that if I use the "Try it out!" feature and select both category1 and category2, the URL formed should contain:
?categories=category1,category2
However, instead SwaggerUI forms that part of the URL as follows:
?categories=category1&categories=category2
Thus, it seems that SwaggerUI is treating the parameter as though explode is set to true.
How can I get SwaggerUI to go with the comma-separated formulation as that's what the server is expecting?

The issue was that the explode and style properties should have been placed at the same level as schema, not nested inside of it.
parameters:
- in: query
name: categories
style: form
explode: false
schema:
type: array
items:
type: string
enum:
- category1
- category2

Related

OpenAPI spec: default value of query param is ignored

I've described a param within an OpenAPI 3 spec as
review_requests:
get:
tags:
- dashboard
operationId: reviewRequests
parameters:
- name: page
in: query
default: 0
description: Page number
schema:
type: integer
responses:
200:
description: OK
After compilation I see that the default value is missing from Java code and the param is actually described like:
#Valid #RequestParam(value = "page", required = false) Integer page
and instead of 0 I receive null if the param is not supplied in GET request.
As far as I understand it should be
#Valid #RequestParam(value = "page", required = false, defaultValue = "0") Integer page
Is it a bug or am I doing something wrong?
Finally I've found the solution: in OpenAPI 3.x, the default value must be specified within the parameter's schema. In other words instead of
parameters:
- name: page
in: query
default: 0
description: Page number
schema:
type: integer
it should be
parameters:
- name: page
in: query
description: Page number
schema:
type: integer
default: 0

How to specify required properties on a requestBody object in an openApi project?

I have a yaml file for an openapi project that looks something like this...
components:
schemas:
Thing:
type: object
properties:
id:
type: integer
prop1:
type: string
prop2:
type: string
prop3:
type: string
paths:
/things:
summary: Create a thing
requestBody:
description: Thing object
content:
application/json:
schema:
$ref: '#/components/schemas/Thing'
required: true
/things/{id}:
put:
summary: Update a thing
parameters:
- name: id
in: path
description: Thing id
schema:
type: integer
requestBody:
description: Thing object
content:
application/json:
schema:
$ref: '#/components/schemas/Thing'
required: true
I am wondering:
Is there a way to configure this so that when creating a "thing" the list of required properties is different than when "updating" a thing? (If I add the 'required' definition to components it affects all paths the same.)
For example, when creating a thing, prop1, prop2, and prop3 may all be required. But when updating a thing, only prop1 may be required.
Thanks!
You can accomplish this by using specific objects for "update" and "create", which inherit from Thing and impose the restrictions you need:
Thing:
type: object
required:
- id
additionalProperties: false
properties:
id:
type: integer
prop1:
type: string
prop2:
type: string
prop3:
type: string
ThingUpdate:
allOf:
- $ref: '#/components/schemas/Thing'
minProperties: 2
ThingCreate:
allOf:
- $ref: '#/components/schemas/Thing'
required:
- prop1
- prop2
- prop3
You then obviously need to modify your POST /things endpoint to take a ThingUpdate in the request body rather than just a Thing, and likewise for PUT /things/{id} and ThingCreate.
To accomplish the "update" validation, notice that in the Thing base object I specified additionalProperties: false and in ThingUpdate I specified minProperties: 2; that enforces that there need to be at least 2 properties in the "Thing", with no properties other than id, prop1, prop2 and prop3 (I assumed id is required, so I put it at the top of Thing).
For the "create" validation, I simply inherited from the Thing base class and specified that all of the non-id properties are required.
There's some redundancy here with the id parameter, since it's not needed for "create", and for "update" it's specified in the path rather than in the request body. You could remove id from the Thing base object and modify minProperties in ThingUpdate to instead be 1. Then, assuming you intend to add a separate GET /things endpoint where you want to retrieve all Things from your database or wherever, you can create a separate derived object ThingGet that includes allOf: Thing and adds the additional id property (under a properties: object).

Open API 3 - How to describe a query parameter that is an array of integers but can be a single item?

Using Open API 3.0.1, I'm trying to describe a query parameter of type "integer", lets say we call it ids, that can be alone or can be an array.
For example:
/my-endpoint?ids=111
or
/my-endpoint?ids=111&ids=222
I did try:
- name: ids
in: query
required: false
schema:
type: array
items:
type: integer
And I understand that style: form and explode: true are the default.
But when I validate this with actual requests (I use express-openapi-validate which is a wrapper around Ajv), I get those errors:
/my-endpoint?ids=111
"Error while validating request: request.query.ids should be array"
/my-endpoint?ids=111&ids=222&ids=333
"Error while validating request: request.query.ids[0] should be integer"
And If I use "string" instead of "integer":
- name: ids
in: query
required: false
schema:
type: array
items:
type: string
/my-endpoint?ids=111
"Error while validating request: request.query.ids should be array"
/my-endpoint?ids=111&ids=222&ids=333
Valid!
How should I describe this ids parameter, which must be integer values?
UPDATE: I now understand that any query parameters will be a string when deserialized by an Express server (which I use). But I'm still unable to have a single element array to work!
After the comment from #Helen, I did try another validation library, express-openapi-validator and now it works well with:
- name: ids
in: query
required: false
style: form
explode: true
schema:
type: array
items:
type: integer
With express-openapi-validate, the only way I've been able to make it work is using:
- name: ids
in: query
required: false
schema:
anyOf:
- type: array
items:
type: string
pattern: '^\d+$'
- type: string
pattern: '^\d+$'
So I suggest you use express-openapi-validator with an Express server.

Swagger ui - call parameters from components

I use swagger ui with swaggerapi/swagger-ui docker image. I try to use parameters defined in components in one of my paths, but that doesn't work. Where is the problem ?
In my index.yaml file
components:
...
parameters:
Pagination:
- in: query
name: page
schema:
type: integer
required: false
description: The page to go to
- in: query
name: per_page
schema:
type: integer
required: false
description: The number of items per page
...
In my path file
parameters:
$ref: '../index.yaml#/components/parameters/Pagination'
Thank you for any help
OpenAPI lets you $ref individual parameters, but not a group of parameters. So if you have several common parameters, you need to create separate definitions for them in the components/parameters section. Also, required is a parameter attribute and not a schema attribute:
components:
parameters:
pageParam: # <-----
in: query
name: page
schema:
type: integer
required: false # <-----
description: The page to go to
perPageParam: # <-----
in: query
name: per_page
schema:
type: integer
required: false # <-----
description: The number of items per page
Then, in your path file, use:
parameters:
- $ref: '../index.yaml#/components/parameters/pageParam'
- $ref: '../index.yaml#/components/parameters/perPageParam'

Swagger UI displaying array example as null

I use OpenAPI 3.0.0 and want to pass an array of Items as a parameter in the requestBody. My API definition looks like this:
post:
tags:
- test
summary: Test dummy
operationId: requestBodyTests
requestBody:
description: test the body
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/Items'
components:
schemas:
Items:
type: array
items:
$ref: '#/components/schemas/Item'
examples:
- id: bla
text: blubb
- id: bla
text: blubb
Item:
type: object
properties:
id:
type: string
name:
type: string
Swagger UI displays the request body example as follows:
and the request body schema as follows:
Why does it show an orderedmap instead of my normal objects?
Can someone tell me how to do the spec right for having the array with items correct?
Examples inside schemas use the example keyword (singular), not examples (plural).
Also, your YAML indentation is wrong - Items and Item must be indented under schemas, list items in the example must have the same indent, etc. If you paste your spec into http://editor.swagger.io, it will point out syntax errors.
Here's the fixed version:
components:
schemas:
Items:
type: array
items:
$ref: '#/components/schemas/Item'
example: # <------
- id: bla
text: blubb
- id: bla
text: blubb
Item:
type: object
properties:
id:
type: string
name:
type: string
Moreover, you get an example as 'orderedmap' because the example field is A free-form property.
But represent examples that cannot be naturally represented in JSON or YAML, a string value can be used to contain the example with escaping where necessary. (OpenAPI spec)
We can write an example as 'string' in both ways:
1.
example: '[ currency: USD, amount: 123 ]'
example: |
[
currency: USD,
amount: 123
]

Resources