$ref in response example - swagger

The response example I would like to put in the yaml file is something like:
{
"name": "Element",
"schema": {
"properties": {
"id": {
"type": "string"
},
"extension": {
"type": "array",
"items": {
"$ref": "#/definitions/Extension"
}
}
}
}
}
And the ymal of this example will be:
responses:
200:
description: "successful operation, return the definition of the resource type in the body"
examples:
application/json:
name: Element
schema:
properties:
id:
type: string
extension:
type: array
items:
$ref: '#/definitions/Extension'
As you can see the last line is "$ref: '#/definitions/Extension'", thus Swagger thinks it is a reference which it can not find anywhere in the ymal file.
Is it possible to escape this to get way from being a reference?

This is a bug in Swagger Editor and UI.
As a workaround, define a schema for your response and use a schema example instead. Schema examples are displayed fine in Swagger Editor 3.6.6 and Swagger UI 3.17.5. You might still see a $ref resolution error in the editor, but at least the example is displayed correctly.
responses:
200:
description: "successful operation, return the definition of the resource type in the body"
schema:
$ref: '#/definitions/MyResponseSchema'
definitions:
MyResponseSchema:
type: object
properties:
name:
type: string
schema:
type: object
properties:
...
example: # <------------
name: Element
schema:
properties:
id:
type: string
extension:
type: array
items:
$ref: '#/definitions/Extension'

Related

How to create a response with $ref and add extra properties in OpenAPI 3?

I have created a patient component and using it as a response like this.
description: Success get all patients
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/InventoryItem'
However the response only contains the patient data but I want to add extra properties to my response like this
{
code: 200,
message: "Success get all patients data"
data: [
// Patient data
]
}
What is the syntax to achieve the above response?
By using properties and just add the extra properties like this.
description: Success get all patients
content:
application/json:
schema:
type: object
properties:
status:
type: number
example: 200
message:
type: string
example: Success get all patients
data:
type: array
items:
$ref: '#/components/schemas/Patient'
And your response will be
{
"status": 200,
"message": "Success get all patients",
"data": [
{
// The data
}
]
}

swagger example response not respecting nested allOf

When using the following swagger, the resulting endpoint has an example response that doesn't align with what I believe the swagger (and the models) dictate.
The swagger:
components:
examples: {}
headers: {}
parameters: {}
requestBodies: {}
responses: {}
schemas:
SubSubData:
type: object
properties:
subSubDataProp:
type: string
SubData:
allOf:
- $ref: '#/components/schemas/SubSubData'
- type: object
properties:
subDataProp:
type: string
Data:
allOf:
- $ref: '#/components/schemas/SubData'
- type: object
properties:
dataProp:
type: string
ExampleResponse:
type: object
properties:
data:
$ref: '#/components/schemas/Data'
info:
title: __PROJECT_NAME__
version: 1.0.0
description: |
Add your Swagger description here.
license:
name: ISC
contact:
name: Me
openapi: 3.0.0
paths:
/example:
get:
operationId: GetData
responses:
'200':
description: Ok
content:
application/json:
schema:
$ref: '#/components/schemas/ExampleResponse'
security: []
The expected response:
{
"data": {
"dataProp": "string",
"subDataProp": "string",
"subSubDataProp": "string"
}
}
Actual:
{
"data": {
"dataProp": "string"
}
}
Am I missing something? Or is this a bug in the swagger ui/openapi
It's a bug in Swagger UI:
https://github.com/swagger-api/swagger-ui/issues/5972
The workaround is to move paths before components.

swagger 3/OAS 3 submit file data along with regular data mutlipart request

I have the following swagger code addCustomer for sending a request that includes an image along with other json data. When I run code from swagger hub; it just sends json. Am I defining this right? Shouldn't it send multipart request?
post:
tags:
- customers
summary: Add a new customer to the store
description: ''
operationId: addCustomer
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/NewCustomerWithImageUrl'
application/xml:
schema:
$ref: '#/components/schemas/NewCustomerWithImageUrl'
multipart/form-data:
schema:
$ref: '#/components/schemas/NewCustomerWithImage'
description: Customer object that needs to be added to the store
required: true
NewCustomerWithImage:
type: object
allOf:
- $ref: '#/components/schemas/NewCustomer'
properties:
Image:
type: string
format: binary
Person:
type: object
required:
- first_name
properties:
first_name:
type: string
example: John
last_name:
type: string
example: Doe
email:
type: string
example: john#example.com
phone_number:
type: string
example: 555-555-5555
address_1:
type: string
example: 123 Nowhere Street
address_2:
type: string
example: Apartment 123
city:
type: string
example: Rochester
state:
type: string
example: New York
zip:
type: string
example: '14445'
country:
type: string
example: United States
comments:
type: string
example: A great customer
custom_fields:
type: object
minProperties: 0
maxProperties: 10
additionalProperties:
type: string
example:
secondary phone number: '555-555-5555'
NewCustomer:
type: object
allOf:
- $ref: '#/components/schemas/Person'
properties:
company_name:
type: string
example: PHP Point Of Sale
tier_id:
type: integer
format: uuid
example: 0
account_number:
type: string
example: '3333'
taxable:
type: boolean
example: false
tax_certificate:
type: string
example: '1234'
override_default_tax:
type: boolean
example: false
tax_class_id:
type: integer
format: uuid
example: 0
balance:
type: number
format: float
example: 22.99
credit_limit:
example: null
points:
type: integer
format: int32
example: 333
disable_loyalty:
type: boolean
example: true
amount_to_spend_for_next_point:
type: number
format: float
readOnly: true
example: 10.00
remaining_sales_before_discount:
type: integer
format: int32
readOnly: true
example: 0
xml:
name: Customer
Json sent:
{"first_name":"John","last_name":"Doe","email":"john#example.com","phone_number":"555-555-5555","address_1":"123 Nowhere Street","address_2":"Apartment 123","city":"Rochester","state":"New York","zip":"14445","country":"United States","comments":"A great customer","custom_fields":{"secondary phone number":"555-555-5555"},"company_name":"PHP Point Of Sale","tier_id":0,"account_number":"3333","taxable":false,"tax_certificate":"1234","override_default_tax":false,"tax_class_id":0,"balance":22.99,"credit_limit":null,"points":333,"disable_loyalty":true,"Image":"string"}
Swagger Hub File:
https://app.swaggerhub.com/apis/PHP-Point-Of-Sale/PHP-Point-Of-Sale/1.0#/customers/addCustomer
1) Swagger UI (which SwaggerHub uses) does not yet support form data and file upload for OpenAPI 3.0 definitions. Follow this issue for status updates: https://github.com/swagger-api/swagger-ui/issues/3641 UPD: Swagger UI now supports file uploads for OAS3.
2) If "request that includes an image along with other JSON data" means a multipart request like this –
POST /foo HTTP/1.1
Content-Type: multipart/form-data; boundary=ABCDEF123
--ABCDEF123
Content-Disposition: form-data; name="Customer"
Content-Type: application/json
{
"foo": "bar"
}
--ABCDEF123
Content-Disposition: form-data; name="Image"; filename="image1.png"
Content-Type: application/octet-steam
{…image content…}
--ABCDEF123--
then the request body definition should look like this:
requestBody:
content:
...
multipart/form-data:
schema:
type: object
properties:
Customer: # <--- name of the part in a multipart request
$ref: '#/components/schemas/NewCustomer'
Image: # <--- name of the part in a multipart request
type: string
format: binary
required:
- Customer
- Image
More information:
How to describe a multipart response using OpenAPI (Swagger)? here on SO
Special Considerations for multipart Content in the OpenAPI 3.0 Specification
Multipart Requests on swagger.io
File upload is supported in Open API v 3.0.3
Here's what my swagger.json looks like:
"/media/upload": {
"post": {
"tags": ["Media"],
"name": "Upload Media",
"description": "Uploads a Media file to the server.",
"requestBody": {
"required": true,
"content": {
"multipart/form-data": {
"schema": {
"type": "object",
"properties": {
"media": {
"type": "string",
"format": "base64"
}
}
}
}
}
}
}
}
Here's how it show up in swagger:

In Swagger, what is the responses looks like if I define the response object like this

I want this API to produce JSON in response HTTP body.
responses:
'200':
description: success
schema:
$ref: '#/definitions/Company'
'400':
description: client doesn't exist
definitions:
Company:
description: ''
type: object
properties:
id:
type: string
description: Empty when creating a record
name:
type: string
description: Not empty when creating record, or updating this field
email:
type: string
I think the response body would be:
{
"code": 200,
"company": {...company object...}
}
Is this correct? or
{
"200": {...company object...}
}
Here is the document that swagger tool generated:

Swagger composition / inheritance

I'm trying to document a REST API using Swagger. A simplified JSON response from our API looks like:
{
"data": {
"type": "person"
"id": "1"
"attributes": {
"name": "Joe"
"age": 32
...
}
"links": {
...
}
}
}
or
{
"data": {
"type": "job"
"id": "22"
"attributes": {
"name": "Manager"
"location": "Somewhere"
...
}
"links": {
...
}
}
}
Their Swagger definitions for a successful GET might look like:
'200':
description: OK.
schema:
type: object
properties:
data:
type: object
properties:
id:
type: string
type:
type: string
attributes:
$ref: '#/definitions/person'
or
'200':
description: OK.
schema:
type: object
properties:
data:
type: object
properties:
id:
type: string
type:
type: string
attributes:
$ref: '#/definitions/job'
There's potentially a lot of repetition like this in our Swagger file. Is it possible to define these responses to share the common parts? i.e. I don't want to type out or copy/paste this part tens of times:
'200':
description: OK.
schema:
type: object
properties:
data:
type: object
properties:
id:
type: string
type:
type: string
I couldn't see how this would work using the discriminator field, or using $ref.
You can use allOf to do composition (in conjunction with discriminator you can do inheritance but it's not really functionnal)
allOf is used with an array of schema or reference, it will create a new definition containing all properties of all definitions in the array.
Given that you want some of your definitions to share id and type properties, it is done this way:
swagger: '2.0'
info:
version: 1.0.0
title: API
paths: {}
definitions:
SharedDefinition:
properties:
id:
type: string
type:
type: string
Person:
allOf:
- $ref: '#/definitions/SharedDefinition'
- properties:
firstname:
type: string
lastname:
type: string
JobSubDefinition:
properties:
name:
type: string
Job:
allOf:
- $ref: '#/definitions/SharedDefinition'
- $ref: '#/definitions/JobSubDefinition'
In this example:
Person = SharedDefinition + inline definition
Job = SharedDefinition + JobSubDefinition
More about this in
Writing OpenAPI (Swagger) Specification Tutorial – Part 4 – Advanced Data Modeling (disclosure: I wrote this tutorial)
OpenAPI Specification#models-with-composition

Resources