Enumerating an array of exactly 2 (slightly different) objects in OpenAPI 3.1.0? - yaml

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

Related

How to define Object with multiple properties including an array of objects in OpenAPI?

I am struggling to define a request body in OpenApi. I want to force the user to send me data in the following shape:
{
"test": {
"a": "a",
"b": "b",
"abc": [
{
"type": "abc",
"name": "name"
},
{
"type": "abc",
"name": "name"
}
...more
]
}
}
This is what I tried but it does not seem to work:
schemas:
SampleRequest:
required:
- abc
properties:
abc:
$ref: "#/components/schemas/ABCType"
ABCType:
type: object
required:
- test
properties:
test:
type: array
items:
type: object
properties:
type:
type: string
name:
type: string
Any help appreciated. Thank you
With the currect json I couldn't make such sense but created this. This created a json which replicates yours.
ABCType:
type: object
additionalProperties: false
required:
- a
- b
- abc
properties:
a:
description: A of ABCType
type: string
b:
description: B of ABCType
type: string
abc:
description: Array of ABCType
type: array
items:
$ref: '#/components/schemas/ABCArrayValue'
ABCArrayValue:
type: object
additionalProperties: false
required:
- type
- name
properties:
type:
description: Type of this array value
type: string
name:
description: Name of this array value
type: string

Custom data type for YAML list [duplicate]

This question already has answers here:
How to return an array of objects in SwaggerHub?
(2 answers)
Closed 4 years ago.
I have this schema defined:
User:
type: object
required:
- id
- username
properties:
id:
type: integer
format: int32
readOnly: true
xml:
attribute: true
description: The user ID
username:
type: string
readOnly: true
description: The username
first_name:
type: string
description: Users First Name
last_name:
type: string
description: Users Last Name
avatar:
$ref: '#/components/schemas/Image'
example:
id: 10
username: jsmith
first_name: Jessica
last_name: Smith
avatar: image goes here
xml:
name: user
Works great. The GET /user/{id} call displays the sample data just fine.
I have a second schema that creates an array of the above schema:
ArrayOfUsers:
type: array
items:
type: object
required:
- id
- username
properties:
id:
type: integer
format: int32
xml:
attribute: true
description: The user ID
username:
type: string
description: The username
first_name:
type: string
description: Users First Name
last_name:
type: string
description: Users Last Name
avatar:
$ref: '#/components/schemas/Image'
This also works great. The GET /user call displays the proper structure in an array just fine.
But I'd rather not define this schema twice.
I would like to create a schema that utilizes the first one and stick in an array.
I have failed in this attempt.
I tried it this way:
UserArray:
type: array
items:
type: object
required:
- id
- username
properties:
things:
type: array
items:
oneOf:
- $ref: '#/components/schemas/User'
This attempt gives me an empty array:
[
{}
]
This is not my desired result.
Any hints on this?
An array of User objects is defined as follows:
UserArray:
type: array
items:
$ref: '#/components/schemas/User'

how to pass multi value query params in swagger

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

Putting arrays inside of objects using Swagger 2.0 and YAML

I am currently learning how to document using Swagger because my company is evaluating using it as a standard way of documenting for upcoming projects.
I read online that using YAML is easier to read than using JSON, and since YAML is a subset of JSON I figured it would be alright.
I'm working on the response for the 200 code, I would like to represent something similar to the following structure:
responses:
200:
description: OK.
schema:
title: response
type: object
items:
properties:
title: user
type: array
items:
id:
type: string
name:
type: string
status:
type: integer
Basically I return an object called "response" that contains two variables: An array called "user" that contains several strings (I included just two for the sake of clarity) and another variable (outside of the "user" array) called "status" that contains an integer.
The above code doesn't work, and the editor notifies me that it isn't a "valid response definition".
I'm not sure how to tackle this. I'd appreciate some help on what I'm doing wrong.
Basically I return an object called "response" that contains two variables: An array called "user" that contains several strings (I included just two for the sake of clarity) and another variable (outside of the "user" array) called "status" that contains an integer.
Based on your description, the response is supposed to be as follows (assuming the response is JSON). Basically, you have an object with a nested object:
{
"user": {
"id": "12345",
"name": "Alice"
},
"status": 0
}
This response can be defined as follows:
responses:
200:
description: OK.
schema:
title: response
type: object
required: [user, status]
properties:
user:
type: object
required: [id, name]
properties:
id:
type: string
name:
type: string
status:
type: integer
For convenience, complex schemas with nested objects can be broken down into individual object schemas. Schemas can be written in the global definitions section and referenced from other places via $ref. This way, for example, you can reuse the same schema in multiple operations/responses.
responses:
200:
description: OK.
schema:
$ref: "#/definitions/ResponseModel"
definitions:
ResponseModel:
title: response
type: object
properties:
user:
$ref: "#/definitions/User"
status:
type: integer
required:
- user
- status
User:
type: object
properties:
id:
type: string
name:
type: string
required:
- id
- name

How to define array-of-objects as parameter?

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
]
}

Resources