Swagger, how to put object properties in separate fields in the interface? - swagger

Is it possible in Swagger in the interface to put the properties of an object in separate fields, as shown in the screenshot below? Swagger version 2.0 or 3.0.
Example
Importantly: These individual object fields must be in the request Body.
What i have done now:
1) The code:
requestBody:
content:
application/x-www-form-urlencoded:
schema:
type: object
properties:
example_obj:
type: object
properties:
field1:
type: string
from:
type: object
properties:
field2:
type: string
field3:
type: string
2) my result:
my result

Related

How to display object properties as separate fields in Swagger UI?

I am writing API documentation using OpenAPI 3.0. At the moment I have:
paths:
/script/update:
post:
tags:
- "Script"
summary: Update a script
operationId: updateScript
responses:
'200':
description: OK
"404":
description: Not Found
requestBody:
description: A script object in order to make the request
required: true
content:
application/x-www-form-urlencoded:
schema:
type: object
properties:
subsite_id:
type: string
script:
type: object
properties:
script:
$ref: '#/components/schemas/ScriptType'
type:
type: string
enum:
- custom
- interface
- freshbot
- feeder
- getter
- smcf
status:
$ref: '#/components/schemas/ScriptStatus'
comment:
type: string
format: string
reason:
type: string
format: string
To problem comes when I try to use to Swagger UI.
The only thing that appears is the following:
What I want is that the script object can be filled out field by field for each of the properties it has, like the subsite_id. What am I missing?
Swagger UI 3.x and 4.x do not have a form editor for JSON objects, so all JSON data needs to be entered in the JSON format: { "prop": value, ... }
Here's the corresponding feature request you can track:
https://github.com/swagger-api/swagger-ui/issues/2771

Swagger: variant schema shape dependant on field value

I have a model defined as:
Event:
type: object
properties:
id:
type: string
timestamp:
type: string
format: date-time
type:
type: string
enum:
- click
- open
- sent
click:
type: object
properties:
url:
type: string
title:
type: string
open:
type: object
properties:
subject:
type: string
sent:
type: object
properties:
subject:
type: string
from:
type: string
to:
type: string
However, the shape is actually different depending on the value of the type enum field. It can be one of three, I tried to define the differences in the examples (see below) but this did not work.
As you can see, the below shows three examples, each one is different depending on the type. This is how the API behaves, but it is not straightforward to document this expected behaviour.
examples:
application/json:
- id: >
ad1b12f0-63a8-47b5-9820-3e447143ce7e
timestamp: >
2017-09-29T16:45:20.000+00:00
type: click
click:
url: >
www.some-website-somewhere.org/12345
title: >
Click here!
- id: >
d9e787fa-db49-4bd8-97c3-df45f159295c
timestamp: >
2017-09-29T16:45:20.000+00:00
type: open
open:
subject: >
Have you seen this?
- id: >
30adc194-0f5f-4889-abd4-4fa964d0bb42
timestamp: >
2017-09-29T16:45:20.000+00:00
type: sent
sent:
subject: >
Have you seen this?
from: >
bill#office.gov
to: >
mon#gmail.com
I read a few places that mention this is not possible, but I am hoping to get some "outside the box" thinkers to help me find a solution.
This is possible using model inheritance/composition and discriminator.
First, define the base model Event that contains just the common properties, and mark the type property as discriminator:
definitions:
Event:
type: object
discriminator: type
required:
- type # discriminator property is required
properties:
id:
type: string
example: ad1b12f0-63a8-47b5-9820-3e447143ce7e
timestamp:
type: string
format: date-time
example: 2017-09-29T16:45:20.000+00:00
type:
type: string
enum:
- click
- open
- sent
Then inherit the click/open/sent models from the base Event model via allOf. The names of the child models must be the same as the values of the discriminator property. In your example, the models must be named click, open and sent. If you use Swagger UI, you can add title to override the displayed model names.
click:
title: ClickEvent
allOf:
- $ref: '#/definitions/Event'
- type: object
properties:
click:
type: object
properties:
url:
type: string
example: www.some-website-somewhere.org/12345
title:
type: string
example: Click here!
In operations, use the base model (Event) as the request or response schema:
responses:
200:
description: OK
schema:
$ref: '#/definitions/Event'
The clients should examine the value of the discriminator property (in this example - type) to decide which inherited model to use.
Note for Swagger UI users: Swagger UI and Swagger Editor currently do not support switching models based on discriminator. Follow this issue for updates.
In OpenAPI 3.0 it's easier - you can simply use oneOf to define alternate schemas for a request or response.
responses:
'200':
description: OK
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/ClickEvent'
- $ref: '#/components/schemas/OpenEvent'
- $ref: '#/components/schemas/SentEvent'
# Optional mapping of `type` values to models
discriminator:
propertyName: type
mapping:
click: '#/components/schemas/ClickEvent'
open: '#/components/schemas/OpenEvent'
sent: '#/components/schemas/SentEvent'

Define a response object with an array in YAML using Swagger Editor

I'm working on an API definition in Swagger Editor with YAML. I am trying to represent the following response body:
{
success: true,
ids: [123456, ...]
}
and this is what my YAML looks like:
definitions:
SuccessfulResponse:
type: object
properties:
success:
type: boolean
description: True if the all operations were successful
ids:
type: array
items:
id:
type: string
Ive tried several different ways but like this but nothing seems valid
How do I properly describe the return object that Ive given above?
Here is an example to define a property as an array of string:
photoUrls:
type: array
items:
type: string
Ref: https://github.com/OpenAPITools/openapi-generator/blob/master/modules/openapi-generator/src/test/resources/2_0/petstore.yaml#L661-L667

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.

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

I have a service that can have two different kind of body parameters based on the Content-Type header.
E.g. for path /Pet:
If Content-Type: application/somecustom.resource+json is used, then POST can take up Pet as the body parameter.
If Content-Type: application/somecustom.function+json is used, then POST should take up some different body parameter to invoke a function and return a different response.
Any suggestion on how to manifest this in OpenAPI (Swagger)?
OpenAPI 3.0 supports different schemas per media type.
openapi: 3.0.0
...
paths:
/pet:
post:
requestBody:
required: true
content:
application/somecustom.resource+json:
schema:
$ref: '#/components/schemas/Pet'
application/somecustom.function+json:
schema:
$ref: '#/components/schemas/Foo'
No, it's not possible to define a two different body parameters for the same operation, in the same path item. The path item name are unique by virtue of being property names (and therefore "keys" in the JSON key-value map), and Swagger specification allows at most one body parameter in a given operation.
There are a few alternative approaches to address this need:
Create two separate path items
For example:
/pets/createFromDescription:
post:
summary: Create a pet from a basic description
operationId: createPetFromDescription
parameters:
- name: petDescription
in: body
required: true
schema:
$ref: "#/definitions/PetDescriptionObject"
responses:
200:
description: OK
/pets/createFromCatalog:
post:
summary: Create a pet from a standard catalog entry
operationId: createPetFromCatalogEntry
parameters:
- name: petCatalogEntry
in: body
required: true
schema:
$ref: "#/definitions/PetCatalogEntry"
responses:
200:
description: OK
Create subtypes, with a discriminator
Described in the Swagger–OpenAPI 2.0 specification here.
Example:
/pets:
post:
summary: Create a pet
operationId: createPet
parameters:
- name: petSource
in: body
description: Structured pet information, from which to create the object
required: true
schema:
$ref: "#/definitions/CreatePet_Request"
responses:
200:
description: OK
definitions:
CreatePet_Request:
type: object
properties:
requestVariant:
type: string
required:
- requestVariant
discriminator: requestVariant
PetDescriptionObject:
allOf:
- $ref: "#/definitions/CreatePet_Request"
- type: object
properties:
name:
type: string
description:
type: string
PetCatalogEntry:
allOf:
- $ref: "#/definitions/CreatePet_Request"
- type: object
properties:
SKU:
type: string
Breed:
type: string
Comments:
type: string
Neither of these methods is keyed to the media type of the request. While your request may accept multiple media types, if the use of a particular media type implies some requirement about the request body, you'd have to document that in the description property of the operation or body parameter.

Resources