How to define an array[object] parameter correctly in the query string - OAS 3.0 - swagger-ui

I have a few issues with an array[object] query string definition in OpenAPI 3.0.3:
parameters:
- in: query
name: find
content:
application/json:
schema:
type: array
items:
type: object
minItems: 1
maxItems: 1
properties:
$match:
type: object
description: To specify conditions to filter the result.
properties:
name:
type: string
description: Name of the desired import
1 - Even though I have specified that the array can only have 1 item, Swagger UI allows me to add multiple items.
2 - It seems that Swagger UI doesn't encode the content properly or the way I want it. When I call my function in my code, I pass the parameter after stringifying (JSON.stringify()) and it is sent like below in the URL:
[{%22$match%22:{%22name%22:%22ffghhhjjj%22}}]
which is deserialized correctly: [{"$match":{"name":"ffghhhjjj"}}"]
But when I see the URL in Swagger UI, it is different:
https://.../api/contact-service/v1/imports?find=%5B%22%7B%5C%22%24match%5C%22%3A%7B%5C%22name%5C%22%3A%5C%22ffghhhjjj%5C%22%7D%7D%22%5D&limit=2&skip=0
This is how the parameter looks like after decoding:
["{\"$match\":{\"name\":\"ffghhhjjj\"}}"]
As you can see, it has sent the array item as string as it should be an object or that the whole value should have been in string that it can be deserialized correctly on the server side.
3 - Another problem is that even though I defined the description for my object's properties, Swagger UI doesn't show it. Defining parameters under components also won't show them as it does for the schemas. Any idea that how I can give the user hints about different properties in my parameter object? I need description to explain different ways that the user can fill up the filter. I.e., "name" can be specified in different formats for filtering:
{"name": "item-name"}
to just items with the specified name), OR:
"name": {"$in": ["name-1","name-2"]}
to get all items that their names matches one of the specified names.
I have tried to place minItems and maxItems in the different locations but didn't work. The current location doesn't give me any errors. Also, I have tried to remove the content and application/json properties but didn't make any changes.

Related

Swagger (hub) how to write certain type

I'm on the swaggerhub website and i need to do an API documentation.
I'm trying to define an object with multiple elements, most of which are basic, but one of the properties is another object, NOT ARRAY, but that child object can contain one or more properties (ALL OF SAME TYPE).
I need to make an object that looks like an array.
Lets say my big object is 'User', and the object that gives me problems is 'addresses':
User:
properties:
name:
type: string
adresses:
type: object
Example:
User:
name: Alex
addresses: {
address: {...}
address2: {....}
address3: {....}
}
I have the Address type defined, but 'addresses' must be an object (meaning that it should look like a json, and not with []). How do i make 'addresses' have variable length?? Maybe with 4 addresses, or only 2.
I want to write examples for this in the API documentation, and i want it to be of variable length, because that's how the API actually works, with a JSON, not an array.
Have you checked the OpenAPI Specification page for help on writing parts of your API definition? It's a great resource that goes into depth on how to write multiple aspects of your API.
Specification page is here: https://swagger.io/specification/
You can browse through topics on the left-hand side. What should be helpful here is the sections under Specification > Schema. There's a lot of information on how to write various types of objects.

How to declare query object in the parameters?

I'm trying to define a query object in OpenAPI 3:
parameters:
- name: query
in: query
schema:
type: object
properties:
id:
type: number
required:
- id
But the example value and schema is not shown in Swaager UI.
Is there a bug or am I missing something?
Your definition is correct.
but example value and schema was not shown in swaager ui.
The example is actually shown, in the JSON key/value format:
{
"id": 0
}
"Try it out" will serialize this parameter according to the defined serialization method, in this case as the ?id=<value> query string.
The issue with the schema not being displayed for query parameters of type: object is a known limitation, it's tracked here:
https://github.com/swagger-api/swagger-ui/issues/4581

How do i enter data for nested arrays in swagger ui

I'm building a web api using asp.net webapi 2 and for my documentation i've chosen to go with swagger.
The problem i'm having is that one of my api methods takes a nested array (array of strings inside another array). When testing manually in postman it works great when i type something like this:
http:/localhost:port/setup?array[0]=key1&array[0]=value1&array[1]=key2&array[1]=value2
But in swagger-ui i get one field to type in, with only one parameter per row. And that makes me unable to enter two values for each nested array.
Result should look like this (json):
[["key1","value1"],["key2","value2"]]
Which i have been able to achieve with the query parameters above. While i can only achieve the following in the swagger-ui text field:
[["key1"],["value1"],["key2"],["value2"]]
I have vacuumed the internet for 1-2 hours for an answare but can only find posts asking how to define a nested array in the yaml file. Some errands i've read on the swagger github leaves me thinking that it isn't possible at all. And while it's not a critical feature it would be really nice if all of the tests worked as they should.
So the question is, if possible, how do i type two separate strings in a nested array in swagger-ui.
I am not a pro in any of this stuff. I learned how to use json api's and swagger, all of it this week so please take that in mind while reviewing this.
Thanks in advance!
A nested array is simple:
type: array
items:
type: array
items:
type: string
But OpenAPI/Swagger does not have a way to serialize nested arrays in the query string like in your example.
If the array has a fixed number of items, a possible workaround is to define each nested array as a separate query parameter:
paths:
/setup:
get:
parameters:
- in: query
name: array[0]
required: true
type: array
items:
type: string
collectionFormat: multi # array[0]=key1&array[0]=value1
- in: query
name: array[1]
required: true
type: array
items:
type: string
collectionFormat: multi # array[1]=key2&array[1]=value2
A better approach would be to use a POST request and pass the array in the request body:
paths:
/setup:
post:
consumes:
- application/json
parameters:
- in: body
name: body
required: true
schema:
type: array
items:
type: array
items:
type: string

Using different Swagger Models properties for collection/detail request/response

I'm beginner of Swagger, and I'm trying to define endpoints which have:
Some read-only properties that isn't allowed in request but show in response
Some white-only properties and hidden that allowed in request but not show in response
Some properties only on collection level at /resources, but some other additional details on /resources/resource-id
What I'm doing is defining the following models:
ResourceBaseModel: this saves all the shared properties of all
ResourceBaseModel:
type: object
properties:
shared_properties:
type: string
ResourceCollectionResponse: this is wrapping the response additional properties
ResourceCollectionResponse:
type: array
items:
type: object
allOf:
- $ref: ResourceBaseModel
- type: object
properties:
collection_normal_properties:
type: string
collection_read_only_properties:
type: string
readOnly: true
ResourceDetailResponse: this is adding different properties for response
ResourceDetailResponse:
type: object
allOf:
- $ref: ResourceBaseModel
- type: object
properties:
detail_normal_properties:
type: string
detail_read_only_properties:
type: string
readOnly: true
ResourceRequest: same, add additional and write-only properties
ResourceRequest:
type: object
allOf:
- $ref: ResourceBaseModel
- type: object
properties:
request_write_only_properties:
type: string
This is making every model defined 4 times and I feel it's not efficient.
So here are my questions:
I saw there is a discriminator in Swagger Spec. Should I use this with "allOf" of these extended models? From result, using of not using this discriminator, the result looks the same as long as "allOf" used.
the "readOnly", if defined in base level, still shows in Swagger UI and needs special handling or filtering when using or generating docs. The demo data in request is also showing these readOnly properties in Swagger UI request (but only the model added a label of "read-only"). Is there any better solution besides what I'm trying.
the "white-only", as far as I know, is not supported. Is defining a new model the only way?
I wonder if there will be one day I can define only one model to describe all of the models, or do you think an innovative language that can compile to Swagger YAML can benefit the whole community? Like how Sass/LESS builds CSS?
Thanks for your help and insightes!
OpenAPI 3.0.x supports writeOnly as well as readOnly schema properties. This should allow you to simplify your models, the allOf / discriminator should not be necessary.

Can I specify the response directly in Swagger 2.0?

I am defining my response as per:
responses:
200:
description: 'An authProvider object'
schema:
type: 'array'
items:
$ref: '#/definitions/AuthProvider'
Is it possible for me to directly attach another field or 2 in the response? I would like to add something that I don't want to put into AuthProvider
Whenever $ref is used, it's basically using JSON Reference. By definition (see linked spec), anything defined within the same object as the reference itself is ignored. As such, it is not possible to directly add additional properties alongside with the $ref definition.
That said, you can use composition to 'combine' two objects into one. This is done using the allOf JSON Schema directive. A simple example for such a definition would look like this:
allOf:
-
$ref: "..."
-
properties:
property1:
type: "string"
property2:
type: "boolean"
Note 1: The various Swagger tools out there may not fully support composition at the moment.
Note 2: As always, it's normally better to externalize the definition (even if used only once) rather than being defined inline.

Resources