My use case in the root level json there are 100 fields and out of those 100 fields 90 fields are common and the remaining 10 fields varies for different API's, I need to specify this 90 fields in a global space and on top of that I need to put the 10 different fields
SAMPLE
POST localhost:3000/api/v1/people
{
name: "", age: "", father_name: ""
//other 90 fields
}
POST localhost:3000/api/v1/student
{
//all fields of people and the below fields.
department_name:"", courses_enroled: ""
}
POST localhost:3000/api/v1/teacher
{
//all fields of people and the below fields.
yoe: "", //assume some specific fields
}
I need to define people payload in global space and in student API, I need to ref it.
How to do this in swagger.
whenever I use ref, it replaces al other fields in the same level.
You can extend existing definition in Swagger 3 and higher (not sure which version you are using). Example in yaml (not sure what you use):
definitions:
Response:
description: "Response Object"
type: object
properties:
success:
description: "If action was successful or not"
type: boolean
example: true
message:
description: "Action message"
type: string
example: "Some message"
data:
description: "Response data"
type: Any
nullable: true
ErrorResponse:
allOf:
- $ref: "#/definitions/Response"
- type: object
properties:
success:
example: false
message:
example: "Error message"
data:
example: null
Related
I have a requirement to have two properties in the payload say property1 and propert2. Both are array type. Condition is, that either both can have values, or only one of them will be non-null. But both cannot be null at the same time.
How can I define this requirement in swagger spec, so that I can enforce schema such that both should not be null but any one of them can be null.
Valid Examples:
Ex1--> {"Property1": ["value1"], "Property2": ["value2"]}
Ex2--> {"Property2": ["value2"]}
Ex3--> {"Property1": ["value1"]}
Invalid Example:
{"Property1": [], "Property2": []}
Assuming the object can only contain these two properties (Property1 and/or Property2) and no other properties, your use case can be defined using a combination of object-level minProperties and array-level minItems:
MyObject:
type: object
minProperties: 1 # <-- requires at least one of Property1 or Property2 to be present
properties:
Property1:
type: array
items:
type: string
minItems: 1 # <-----
Property2:
type: array
items:
type: string
minItems: 1 # <-----
If the payload can also contain other properties, the "either Property1 or Property2 must be present" condition can be defined using anyOf + required. This requires OpenAPI 3.x:
# openapi: 3.x.x
MyObject:
type: object
anyOf: # <----------------
- required: [Property1]
- required: [Property2]
properties:
Property1:
type: array
items:
type: string
minItems: 1
Property2:
type: array
items:
type: string
minItems: 1
SomeOtherProperty:
...
How can I define workingDays as array so that dayIndex, dayStart and dayEnd are one object inside?
* /business-calendar/:
* post:
* description: Add a new business calender
* responses:
* '200':
* description: Business calendar added
* requestBody:
* content:
* application/json:
* schema:
* type: object
* example:
* name: "Standard"
* validFrom: "2021-01-01T00:00:00.000Z"
* validTo: "2021-12-31T00:00:00.000Z"
* useHolidays: true
* workingDays:
* dayIndex: 0
* dayStart: "8:00"
* dayEnd: "20:00"
*/
Current output:
{
"name": "Standard",
"validFrom": "2021-01-01T00:00:00.000Z",
"validTo": "2021-12-31T00:00:00.000Z",
"useHolidays": true,
"workingDays": {
"dayIndex": 0,
"dayStart": "8:00",
"dayEnd": "20:00"
}
}
Desired output:
{
"name": "Standard",
"validFrom": "2021-01-01T00:00:00.000Z",
"validTo": "2021-12-31T00:00:00.000Z",
"useHolidays": true,
"workingDays": [
{
"dayIndex": 0,
"dayStart": "8:00",
"dayEnd": "20:00"
}
]
}
The way I would approach this would be to create a workingDay object, and pass an array of those objects in the request body. To do this, you'll want workingDay to be defined as a schema with the desired properties in the schema section under components. Notice the use of '$ref' to point an example workingDay object:
https://swagger.io/docs/specification/using-ref/
workingDay:
description: describe my working days
type: object
example:
$ref: "#/components/examples/workingDay"
properties:
dayIndex:
description: index my day
type: foo
dayStart:
description: start my day
type: bar
dayEnd:
description: end my day
type: baz
The example object might look something like this:
https://swagger.io/docs/specification/adding-examples/
workingDay:
summary: example values of a workingDay object
value:
dayIndex: 0
dayStart: 8:00
dayEnd: 20:00
Then when you go to describe the endpoint requestBody, it'll look more like this:
https://swagger.io/docs/specification/describing-request-body/
requestBody:
content:
application/json:
schema:
type: object
properties:
name:
type: string
validFrom:
type: string
validTo:
type: string
useHolidays:
type: bool
workingDays:
type: array
items:
$ref: "#/components/schemas/workingDay"
In the OpenAPI definition below, the parameter definition causes the parser error "bad indentation of a mapping entry". What is wrong? Error at "properties" (last 5th line)
responses:
'200':
description: OK
content:
application/json;charset=UTF-8:
schema:
type: object
properties:
creationTime:
type: string
format: date-time
description: >-
The date and time the response was created in GMT time
with a format of "MM-dd-yyyy HH:mm:ss.SSSZ"
example: '03-12-2019 14:05:35.182-0500'
response:
type: array
description: ''
properties:
recordID:
type: string
maxLength: 20
externalID:
The error occurs because the properties keyword is indented more than its sibling type and description keywords.
response:
type: array
description: ''
properties: # <---- Indentation doesn't match the sibling
# `type` and `description` keywords
However, type: array schemas need items, not properties.
It looks like the response key is either missing some keywords or has extra keywords. The correct definition for response would be:
response:
type: object # <----------
description: ''
properties: # <----------
recordID:
type: string
maxLength: 20
externalID:
...
or
response:
type: array
description: ''
items: # <----------
type: object # <----------
properties: # <----------
recordID:
type: string
maxLength: 20
externalID:
...
depending on what you need.
I need to specify that my endpoint has a mandatory field, an optional field and open to any number of fields(which can be sent without validation).
For e.g. for an endpoint /user
user_id: str, mandatory
timestamp_utc: timestamp, optional
..*accept_any_extra_fields**..
So if someone sends the following json to my endpoint, the endpoint should accept it
{ "user_id": 1,
"name": "Sam",
"location": "USA"
}
but it fails if the following json is sent as it does not contain user_id.
{ "name": "Sam",
"location": "USA"
}
it should fail.
I'm new to OpenAPI/Swagger. I know I can send the extra data. But how do I describe this as documentation on OpenAPI so a person(or a program) knows that they can send any field (e.g. name, location) along with user_id
Do you use Java-Spring? I use Swagger in Annotation approach in my Spring controllers, and in java code, you can specify params that you need in this way:
#ApiOperation(value = "Get user", notes = "Get a user by the given filters")
#GetMapping("v1/users")
public UserDTO getUsers(#ApiParam(value = "User id", required = true)
#RequestParam(value = "user_id", required = true) String userId,
#ApiParam(value = "Date", required = false)
#RequestParam(value = "timestamp_utc", required = false)
#DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime utc,
#ApiParam(value = "Some other", required = false)
#RequestParam(value = "some_other", required = false) String someOther){
return service.getUser(userId, utc, someOther);
}
The annotation #ApiOperation is to describre your endpint.
The annotation #ApiParam is to describe the param characteristics, and the attribute required is to inform that is.
Don't forget to add the swagger dependencies, here is on maven.
You also have the possibility to generate your API documentation in YAML. An example is here . Please check the endpoint for user/login.
I hope my answer will help you.
The additionalProperties keyword allows a schema to have extra properties besides those listed in the properties section.
MyModel:
type: object
required:
- user_id
properties:
user_id:
type: string
timestamp_utc:
type: string
additionalProperties: true # OpenAPI 3.0
# or
# additionalProperties: {} # OpenAPI 2.0
Actually OpenAPI schemas are open to extension by default, in the absence of the additionalProperties keyword. However, some tools consider the absence of additionalProperties as "additional properties NOT allowed", so it's best to add additionalProperties: true / additionalProperties: {} explicitly just in case.
If the extra properties are limited to a specific data type, e.g. string, use
additionalProperties:
type: string
If I have the following example where Settings definition is embedded in Thing via composition:
definitions:
Settings:
properties:
foobar:
type: number
format: double
boofar:
type: string
Thing:
properties:
allOf:
$ref: '#/definitions/Settings'
name:
type: string
If I define a method to POST a Thing in editor.swagger.io, it ends up constructing JSON that looks like this:
{
settings: {
foobar: 1,
boofar: "text here"
},
name: "some name"
}
I want to embed a model definition with composition but without the additional nested property definition -- is this possible? This is the JSON structure I would like to have for Thing:
{
foobar: 1,
boofar: "text here",
name: "some name"
}
Is there a way to achieve this?
Your example do not really use composition as allOf is a property.
allOf is supposed to be on the root of the definition and it's an array of schema (reference or inline).
Here's the proper way to use allOf for your example:
swagger: '2.0'
info:
title: API
version: 1.0.0
paths:
/thing:
get:
responses:
200:
description: OK
schema:
$ref: '#/definitions/Thing'
definitions:
Settings:
properties:
foobar:
type: number
format: double
boofar:
type: string
Thing:
allOf:
- $ref: '#/definitions/Settings'
- properties:
name:
type: string
Resulting rendering in SwaggerUI: