I have following service in swagger.yml. The service is written so that page_id can be passed multiple times. e.g /pages?page_id[]=123&page_id[]=542
I checked this link https://swagger.io/specification/ but couldnt understand how could i update yml so i could pass id multiple times.
I see that i have to set collectionFormat but dont know how.
I tried updating it like below but no luck https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md.
it generates url like 'http://localhost:0000/pages?page_id=123%2C%20542`
'/pages':
get:
tags:
-
summary: get the list of pages
operationId: getPages
produces:
- application/json
parameters:
- name: page_id
in: query
description: some description
required: false
type: string
collectionFormat: multi
- name: page_detail
in: query
description: some description
required: false
type: string
responses:
'200':
description: OK
'401':
description: Authentication Failed
'404':
description: Not Found
'503':
description: Service Not Available
You are almost there. Name the parameter page_id[], make it type: array and use collectionFormat: multi:
parameters:
- name: page_id[]
in: query
description: some description
required: false
type: array
items:
type: string # or type: integer or whatever the type is
collectionFormat: multi
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.
http://example.com/pages?page_id%5B%5D=123&page_id%5B%5D=456
From the docs:
parameters:
- name: id
in: path
description: ID of pet to use
required: true
schema:
type: array
style: simple
items:
type: string
You have to define the parameter as array.
How to add default values to the query parameter of type array:
parameters:
- name: 'liabilityType[]'
in: query
description: liabilityType filters the servicers list according to liability types.
required: false
schema:
type: array
items:
type: string
collectionFormat: multi
value:
- CAR
- HOUSE
I have attached a picture of how this code would look like in Swagger UI
[1]: https://i.stack.imgur.com/MSSaJ.png
Related
I need to document a REST endpoint that takes the following request body:
{
"variables": [
{
"name": "groupGuid",
"value": "...",
"typeConstraint": "string",
},
{
"name": "addMembership",
"value": "...",
"typeConstraint": "boolean",
}
]
}
The variables array must take exactly 2 objects:
one with the required name groupGuid and typeConstraint string,
and the other with the required name addMembership and typeConstraint boolean.
The type of their respective values are specified by typeConstraint, but the actual values of the value properties are otherwise unconstrained.
Currently, I've got this, which is very underspecified (and possibly wrong) and relies on notes I've manually included:
'/test':
post:
requestBody:
content:
application/json:
schema:
type: object
properties:
variables:
type: array
uniqueItems: true
description: 'Must contain exactly 2 objects, with the following `name`s: (1) `groupGuid`: GUID of the group, (2) `addMembership`: Whether the task will add (true) or remove (false) members from the group.'
items:
type: object
additionalProperties: false
properties:
name:
enum:
- groupGuid
- addMembership
type: string
value:
type:
- string
- boolean
typeConstraint:
type: string
enum:
- string
- boolean
description: The type of `value`.
Is it possible to properly spec these requirements in YAML / OpenAPI 3.1.0, and if so, how? Thanks.
If what you want is to show both objects in the example body and accept either or both of them, perhaps you could use anyOf.
Below an example
paths:
/test:
post:
tags:
- Test
description: "Must contain exactly 2 objects, with the following `name`s: (1) `groupGuid`: GUID of the group, (2) `addMembership`: Whether the task will add (true) or remove (false) members from the group."
requestBody:
required: true
content:
application/json:
schema:
properties:
variables:
type: array
uniqueItems: true
items:
anyOf:
- $ref: '#/components/schemas/Object1'
- $ref: '#/components/schemas/Object2'
responses:
'200':
description: Sucess
components:
schemas:
Object1:
type: object
description: "The value here is string"
properties:
name:
type: string
value:
type: string
typeConstraint:
type: string
Object2:
type: object
description: "The value here is boolean"
properties:
name:
type: string
value:
type: string
typeConstraint:
type: boolean
I am using Open API 3.0 to generate the code.
Below is Open API specification:
spec.yml:
openapi: 3.0.0
info:
version: 1.0.0
title: Store API
description: A store API to get store and related department information
termsOfService: http://www.***.com/xml,
contact:
name: MTAMP Support,
url: http://www.****.com/xml,
email: mtamp#mt.com
paths:
/api/stores:
get:
summary: To get all stores
tags:
- Stores
description: To get all store and department information
operationId: getStores
responses:
'200':
description: Successful response
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/StoresDTO'
/api/stores/{storeId}:
parameters:
- in: path
name: storeId
required: true
schema:
type: integer
format: int64
description: Pass a store Id as a parameter
get:
summary: To get store infomation based on storeId. When you pass storeId as request related store information along with department will get returned.
tags:
- Stores
description: To get store information based on storeId
operationId: getStoresById
x-mtampException:
- throws com.mt.mtamp.storeservice.exception.ResourceNotFoundException
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/StoresDTO'
/api/stores/{storeId}/regions/{regionId}:
parameters:
- in: path
name: storeId
required: true
schema:
type: integer
format: int64
description: Pass a store Id as a parameter
- in: path
name: regionId
required: true
schema:
type: integer
format: int64
description: Pass a region Id as a parameter
get:
summary: To get store infomation based on regionId. When you pass region as request related store information will get returned.
tags:
- Stores
description: To get store information based on regionId.
operationId: getStoresByRegionId
x-mtampException:
- throws com.mt.mtamp.storeservice.exception.ResourceNotFoundException
responses:
'200':
description: Successful response
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/StoresDTO'
/api/departments/{departmentId}/stores/{storeId}:
parameters:
- in: path
name: storeId
required: true
schema:
type: integer
format: int64
description: Pass a department Id as a parameter
- in: path
name: departmentId
required: true
schema:
type: integer
format: int64
description: Pass a store Id as a parameter
get:
summary: To get department infomation based on storeId. When you pass store Id as request related department information will get returned.
tags:
- Departments
description: To get department information based on storeId.
operationId: getDepartmentsByStoreId
x-mtampException:
- throws com.mt.mtamp.storeservice.exception.ResourceNotFoundException
responses:
'200':
description: Successful response
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/DepartmentsDTO'
/api/regions/{regionId}/customer/{customerId}:
parameters:
- in: path
name: customerId
required: true
schema:
type: integer
format: int32
description: Pass a customer Id as a parameter
- in: path
name: regionId
required: true
schema:
type: integer
format: int64
description: Pass a region Id as a parameter
get:
summary: To get region based on customer Id.
tags:
- Regions
description: To get region information based on customer Id.
operationId: getRegionByCustomerId
x-mtampException:
- throws com.mt.mtamp.storeservice.exception.ResourceNotFoundException
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/RegionsDTO'
components:
schemas:
StoresDTO:
required:
- storeName
- storeLocation
properties:
storeId:
type: integer
format: int64
example: 1
storeName:
type: string
example: FreshPro
storeLocation:
type: string
example: Germany
departments:
type: array
items:
$ref: '#/components/schemas/DepartmentsDTO'
DepartmentsDTO:
required:
- departmentId
- departmentName
properties:
departmentId:
type: integer
format: int64
example: 42
departmentName:
type: string
example: Vegetables
storeId:
type: integer
format: int64
example: 34
RegionsDTO:
required:
- regionId
- regionName
properties:
regionId:
type: integer
format: int64
example: 22
regionName:
type: string
example: Fresh Pro
customerId:
type: integer
example: 19
stores:
type: array
items:
$ref: '#/components/schemas/StoresDTO'
Generated Code:
#RequestMapping(
method = RequestMethod.GET,
value = "/api/stores/{storeId}/regions/{regionId}",
produces = { "application/json" }
)
ResponseEntity<List<StoresDTO>> getStoresByRegionId(
#Parameter(name = "storeId", description = "Pass a store Id as a parameter", required = true) #PathVariable("storeId") Long storeId,
#Parameter(name = "regionId", description = "Pass a region Id as a parameter", required = true) #PathVariable("regionId") Long regionId
)throws com.mt.mtamp.storeservice.exception.ResourceNotFoundException;
Here when I load the swagger for example for service /api/stores/{storesId}/regions/{regionId}, I am seeing the response showing stores and departments object.
This API returns a list of store object but in swagger it showing be single store object.
Can I know how to fix this swagger and Openapi issue
I've logged in to swaggerhub and generated a sample inventory API which is part of their template.
In codegen options selected spring as server. ticked on useBeanValidation checkbox. Generated the code, tested it. Validations are working properly as expected except only one thing. I don't want to allow any additional property on the POST payload.
NB: The openAPI specification doesn't have 'additionalProperties' flag specified. Which defaults it to 'false' in my understanding. I tried to explicitly specify the same too. but no luck. There is no exception thrown while I add an additionalProperty.
The OpenAPI specification
openapi: 3.0.0
servers:
# Added by API Auto Mocking Plugin
- description: SwaggerHub API Auto Mocking
url: https://virtserver.swaggerhub.com/xxxx/apionopenApi3/1.0.0
info:
description: This is a simple API
version: "1.0.0"
title: Simple Inventory API
contact:
email: you#your-company.com
license:
name: Apache 2.0
url: 'http://www.apache.org/licenses/LICENSE-2.0.html'
tags:
- name: admins
description: Secured Admin-only calls
- name: developers
description: Operations available to regular developers
paths:
/inventory:
get:
tags:
- developers
summary: searches inventory
operationId: searchInventory
description: |
By passing in the appropriate options, you can search for
available inventory in the system
parameters:
- in: query
name: searchString
description: pass an optional search string for looking up inventory
required: false
schema:
type: string
- in: query
name: skip
description: number of records to skip for pagination
schema:
type: integer
format: int32
minimum: 0
- in: query
name: limit
description: maximum number of records to return
schema:
type: integer
format: int32
minimum: 0
maximum: 50
responses:
'200':
description: search results matching criteria
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/InventoryItem'
'400':
description: bad input parameter
post:
tags:
- admins
summary: adds an inventory item
operationId: addInventory
description: Adds an item to the system
responses:
'201':
description: item created
'400':
description: 'invalid input, object invalid'
'409':
description: an existing item already exists
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/InventoryItem'
description: Inventory item to add
components:
schemas:
InventoryItem:
type: object
additionalProperties: False
required:
- id
- name
- manufacturer
- releaseDate
properties:
id:
type: string
format: uuid
example: d290f1ee-6c54-4b01-90e6-d701748f0851
name:
type: string
example: Widget Adapter
releaseDate:
type: string
format: date-time
example: '2016-08-29T09:12:33.001Z'
manufacturer:
$ref: '#/components/schemas/Manufacturer'
Manufacturer:
required:
- name
properties:
name:
type: string
example: ACME Corporation
homePage:
type: string
format: url
example: 'https://www.acme-corp.com'
phone:
type: string
example: 408-867-5309
type: object
additionalProperties: False
Got 400 for this payload on post API.
{
"id": "7f125802-7840-4ff0-8ddb-7c78c0948987",
"name11111": "Widget Adapter",
"releaseDate": "2016-08-29T09:12:33.001Z",
"manufacturer": {
"name": "ACME Corporation",
"homePage": "",
"phone": "408-867-5309"
}
}
Expected 400 but didn't get on this payload on post
{
"id": "7f125802-7840-4ff0-8ddb-7c78c0948983",
"name": "Widget Adapter",
"releaseDate": "2016-08-29T09:12:33.001Z",
"manufacturer": {
"name": "ACME Corporation",
"homePage": "",
"phone": "408-867-5309"
},
"newkey" : "newValue"
}
Can anybody pls help on this.. I want to completely disallow additional properties and throw a 400 on those requests..
The default for additionalProperties is actually True, not False.
Adding false does not cause the swagger-codegen for Spring to actually disallow additional fields though, annoyingly enough. After a few hours of running in the wrong direction I found the solution:
In application.properties
spring.jackson.deserialization.FAIL_ON_UNKNOWN_PROPERTIES=true
I had been having the same trouble and have tried to leverage filters but have had problems tying the models that are used in the automatic deserialization of #RequestBody to the servlet request and keeping the behavior consistent across model changes. Coming to that conclusion required writing quite a bit of unnecessary boilerplate and wasting a lot of time.
I also tried to find a way to inject some behavior in the automatic use of the model or any model annotation that would change how the model automatically disregards additional fields without reporting the bad request. After exhausting the road of annotations I found the solution.
I am quite new to Swagger, so this might be a basic question.
I am able to create .yml file for an API which takes an array of integers as parameter, as follows:
Add samples
---
tags:
- MY API
parameters:
- name: my_id
in: path
type: integer
required: true
description: Some des
- name: body
in: body
schema:
id: add_samples
required:
- sample_ids
properties:
sample_ids:
type: array
items:
type: integer
description: A list of sample ids to be added
responses:
'200':
description: Added samples.
'400':
description: Error adding samples.
This is what I send to the above API and everything works fine:
{"sample_ids": [475690,475689,475688]}
Now, instead of an array of integers, if I want to use some complex object as parameter, how to do it?
E.g. If this is what I want to send:
{"sample_ids": [{
"sample_id": "7",
"some_prop": "123"
},
{
"sample_id": "17",
"some_prop": "134"
}]}
How should the .yml file look? I have tried something like this and it doesn't seem to work:
Add sample
---
tags:
- Samples API
models:
Sample:
id: Sample
properties:
sample_id:
type: string
default: ""
description: The id for this sample
some_prop:
type: integer
description: Some prop this sample
parameters:
- name: body
in: body
schema:
id: add_sample
required:
- sample_ids
properties:
samples:
type: array
description: A list of samples to be added
items:
$ref: Sample
responses:
'201':
description: Created a new sample with the provided parameters
'400':
description: SOME ERROR CODE
This one seems to work, mostly:
Add sample
---
tags:
- Samples API
models:
Sample:
id: Sample
properties:
sample_id:
type: string
default: ""
description: The id for this sample
some_prop:
type: integer
description: Some prop this sample
parameters:
- name: body
in: body
schema:
id: add_sample
required:
- sample_ids
properties:
samples:
type: array
description: A list of samples to be added
items:
$ref: Sample
responses:
'201':
description: Created a new sample with the provided parameters
'400':
description: SOME ERROR CODE
Now only problem is, in the Swagger UI, it is not showing member variables and their default values. Rather is showing it as null:
{
"samples": [
null
]
}
i am new to swagger and following is the code i was trying to edit in the online editor. But it is displaying an error which says "Not a valid parameter definition" at the parameters field.
# Example YAML to get you started quickly.
# Be aware that YAML has indentation based scoping.
# Code completion support is available so start typing for available options.
swagger: '2.0'
# This is your document metadata
info:
version: "0.0.0"
title: <test>
# Describe your paths here
paths:
# This is a path endpoint. Change it.
/test:
# This is a HTTP operation
post:
# Describe this verb here. Note: you can use markdown
description: Pass list of input parameter.
# This is array of GET operation parameters:
operationId: test
produces:
- application/json
- application/xml
- text/xml
- text/html
parameters:
-
name: value
in: body
description: Input parameter list
required: true
schema:
type: array
items:
type: object
properties:
Name:
type: string
Age:
type: integer
format: int32
Address:
type: string
Company:
type: string
WorkExperience:
type: integer
format: int32
# Expected responses for this operation:
responses:
# Response code
200:
description: Successful response
# A schema describing your response object.
# Use JSON Schema format
schema:
title: ArrayOfPersons
type: array
items:
title: Person
type: object
properties:
name:
type: string
single:
type: boolean
The following error is displayed in the swagger previewer
Swagger Error
Not a valid parameter definition
Jump to line 28
Details
Object
code: "ONE_OF_MISSING"
params: Array [0]
message: "Not a valid parameter definition"
path: Array [5]
schemaId: "http://swagger.io/v2/schema.json#"
inner: Array [2]
level: 900
type: "Swagger Error"
description: "Not a valid parameter definition"
lineNumber: 28
This is an code intending error.
schema:
type: array
items:
type: object
properties:
The "type: array" definition in the schema field was not indented properly.
parameters:
-
name: value
in: body
description: Input parameter list
required: true
schema:
type: array
items:
type: object
properties:
Name:
type: string
Age:
type: integer
format: int32
Address:
type: string
Company:
type: string
WorkExperience:
type: integer
format: int32