I don't understand default values for object parameters in swagger. The documentation doesn't seem to have any examples.
For example:
components:
parameters:
coordinates:
in: query
name: coordinates
description: Test Obj Parameter
schema:
type: object
properties:
lat:
type: number
default: 0.0
long:
type: number
default: 0.0
required: false
paths:
/my/path/:
get:
parameters:
- $ref: "./common.yaml#/components/parameters/coordinates"
default: [51.47, 0.0]
in the path's parameters section?The code that's generated with default: [51.47, 0.0]
, default: {"lat":51.4, "lon":0.0}
and with no default specified is the same.
Making one of the member fields required seems to only add a isSet flag, setteng and unsetter functions.
There are a few different questions here, so I'm going to split them up into three topics
Disclaimer: You didn't provide any generator commands, so I am using the gradle-plugin with the spring
generator for most of my examples. I can update this to use a different plugin or generator if you are unable to get your code working with what I provide.
The swagger documentation for parameters has a section called Default Parameter Values. In that section, the documentation states
"Use the default keyword in the parameter schema to specify the default value for an optional parameter. The default value is the one that the server uses if the client does not supply the parameter value in the request. The value type must be the same as the parameter’s data type."
It also has the following example:
parameters:
- in: query
name: offset
schema:
type: integer
minimum: 0
default: 0
required: false
description: The number of items to skip before starting to collect the result set.
- in: query
name: limit
schema:
type: integer
minimum: 1
maximum: 100
default: 20
required: false
description: The number of items to return.
The coordinates schema you provided in your question is a valid schema. I even went so far as to test it in my own generator, using the spring
generator, and I was able to get a valid object created. This object had the below fields defined:
@JsonProperty("lat")
private BigDecimal lat = new BigDecimal("0.0");
@JsonProperty("long")
private BigDecimal _long = new BigDecimal("0.0");
As you can see, the default values were defined as expected.
Plainly speaking, no. The swagger documentation states:
Any sibling elements of a $ref are ignored. This is because $ref works by replacing itself and everything on its level with the definition it is pointing at.
Consider the following schema:
components:
schemas:
EmployeeInfo:
type: object
properties:
name:
description: an employee's name
$ref: '#/components/schemas/Name'
address:
$ref: '#/components/schemas/Address'
description: an employee's address
CustomerInfo:
type: object
properties:
name:
description: a customer's name
$ref: '#/components/schemas/Name'
address:
$ref: '#/components/schemas/Address'
description: a customer's address
Name:
description: a standard name
type: object
properties:
firstName:
type: string
lastName:
type: string
Address:
description: a standard address
type: object
properties:
street:
type: string
city:
type: string
state:
type: string
zip:
type: string
This schema appears valid, and will pass most validation tools. However, if we look at the employee info object in our swagger-ui, we will see that the descriptions for the name and address ignore the description in the schema.
This is because, as the documentation states, anything else contained at the same level as the $ref
is ignored.
The same is true for any defaults you try to set at the path level. If you are referencing a schema contained elsewhere, than the default values will be ignored.
This is more of a style choice, and falls back to the age old answer: "it depends". Remember that swagger-ui is in part a REST interface, but is also your documentation. What are you doing with these coordinates? What happens if the users don't supply them? What is expected to happen? Does providing them or not providing them change your APIs response schema?
Most importantly, do you want your users to know of the coordinates default values?
For example, you can easily add a method in your controller that sets the values to something if they are not provided in the request. You don't have to tell your users about this. This would be a default value without documentation. If you want to tell your users about it, you can set an example and a description that explains the default value.
If the value is required, I personally prefer to make the users provide it. This ensures they know what they are requesting and what they are getting. If the value is optional, it all comes down to style and documentation. I prefer explaining the usage to my users, so I will document the default so they are aware of how it is being used. This will also result in fields being set automatically, such as in the Java code above.
Here's a yaml using examples in parameters. You can copy and paste it into swagger editor to see how it renders and displays. When choosing an example to view, notice that the description changes. Also notice that when you click try it out, it will create a request using the example (with the values you have provided in the example:
openapi: 3.0.3
info:
title: My-API
version: 0.0.1
servers:
- url: 'https://my.server.com'
paths:
/employees:
get:
tags:
- Employees
summary: Add a new article to the store
description: Get an Object
operationId: getObject
parameters:
- $ref: '#/components/parameters/employeeInfo'
responses:
'200':
description: Successful operation
components:
parameters:
employeeInfo:
name: employee
in: query
description: The information of the employee
required: false
schema:
$ref: '#/components/schemas/EmployeeInfo'
examples:
Employee Information:
value:
name: Bob Smith
title: Front Desk
responsibilities:
- working
- playing
phone: (123) 555-1234
description: |
This is a description of the manager item.
you can explain default values here.
For example:
**Parameters**:
* **title**:
* defaults to Night Manager if not provided
* Any String is valid, but may return status 404 if the title is not a valid title after validation
* **name**:
* no default value
Manager Information:
value:
name: Kevin Mitchell
title: Night Manager
responsibilities:
- watch Bob
- don't sleep
description: |
This is a description of the manager item.
you can explain default values here.
For example:
**Parameters**:
* **title**:
* defaults to Night Manager if not provided
* Any String is valid, but may return status 404 if the title is not a valid title after validation
* **name**:
* no default value
* must be a valid employee name
schemas:
EmployeeInfo:
description: general employee information
type: object
properties:
name:
type: string
phone:
type: string
pattern: '^(\([0-9]{3}\) |[0-9]{3}-)[0-9]{3}-[0-9]{4}$'
id:
type: string
format: uuid
oneOf:
- $ref: '#/components/schemas/ManagementInfo'
- $ref: '#/components/schemas/GruntInfo'
GruntInfo:
type: object
properties:
responsibilities:
$ref: '#/components/schemas/EmployeeResponsibilities'
ManagementInfo:
type: object
properties:
name:
type: string
default: Bob
title:
type: string
default: Manager
responsibilities:
$ref: '#/components/schemas/ManagerResponsibilities'
ManagerResponsibilities:
description: manager responsibilities
type: array
items:
type: string
enum:
- Meetings
- Sleeping
- Planning
- Rehersing
- Supervising
default:
- meetings
- sleeping
EmployeeResponsibilities:
title: Employee Responsibilities
description: Employee responsibilities
type: array
items:
type: string
enum:
- cleaning
- organizing
- attending
default:
- cleaning
You can now see that each example is available in the drop-down, along with the description of the values.
If you click try it out on the employee example, it will create the following request:
https://my.server.com/employees?name=Bob%20Smith&title=Front%20Desk&responsibilities=working&responsibilities=playing&phone=%28123%29%20555-1234