swagger editor: can't add local reference with $ref - swagger

I'm creating some API through swagger.
I can't understand how I can use $ref with a reference on the same file...
Here's my current swagger file:
openapi: 3.0.0
info:
title: test API
version: "1.0.0"
description: This is a sample API.
servers:
- url: http://api.internal.com/api
paths:
/sources/:
get:
summary: returns all sources given a page and a size
parameters:
- name: page
required: true
in: query
description: Limits the number of items on a page
schema:
type: integer
- name: size
required: true
in: query
description: Specifies a page size
schema:
type: integer
responses:
'200':
$ref: '#/definitions/myElement'
definitions:
myElement:
"data": {
"sources": [
{
"id": "fw5pQ08wMnFfbEE",
"fileName": "test.csv",
"size": 1000000,
"annotatedDate": "2018-10-01 12:00:00",
"metadataContact": "test#test.com",
"canBeIngested": true
}
],
"stats": {
"total": 4000,
"page": 1,
"size": 20
}
}
Now, the problem is that the editor is throwing me this error:
Errors
Schema error should NOT have additional properties
additionalProperty: definitions
Jump to line 0
in the documentation of $ref I can't really find anything helpful...
How can I fix this?

In OpenAPI 3.0, definitions were replaced with components/schemas. This means you need to use:
responses:
'200':
$ref: '#/components/schemas/myElement'
and
components:
schemas:
myElement:
...
Also, your model definition for myElement is not valid. See this guide to learn how to describe objects, properties, etc.

Related

swagger-ui docker image: Help understanding why query parameter using deepObject and explode does not result in the desired query

I'm trying to define OpenAPI for a query parameter that uses a simple type for a deepObject.
According to the OpenAPI spec, the following should work:
openapi: 3.0.3
info:
title: OpenAPI definition
version: 0.0.1
paths:
/example:
get:
parameters:
- name: foo
in: query
required: false
schema:
type: object
minProperties: 1
style: deepObject
explode: true
example: >
{
"bar": "baz"
}
responses:
"200":
description: OK
"400":
description: Bad request
"401":
description: Authorization info missing or invalid
"403":
description: Unauthorized
"404":
description: Not found
Should result in a query such as http://localhost:9080/example?foo[bar]=baz if you use the same input as the given example. However, what I'm getting is http://localhost:9080/example?bar=baz. I've searched around and quadruple checked my syntax to make sure I am doing what I think is being described around the web, but it still doesn't result in the output I think the OpenAPI spec is describing. I feel like I must be doing something wrong and am just not seeing it. Can anyone identify what I am doing wrong?
Note, I also posted this question to the discussion on the swagger-ui GitHub project.
Move style and explode outside the schema, to the parameter level:
parameters:
- name: foo
in: query
required: false
style: deepObject # <-------
explode: true # <-------
schema:
type: object
...

requestBody not displaying subtypes with arrays within a $ref component but shows correctly in response body

I've been struggling with an issue in an openapi 3.0.1 spec json document I've been working on.
The issue I'm seeing in the online swagger editor (editor.swagger.io) is very strange where the Request body Example Value section of a POST does not show the "layers", which is an array defined within my MixBase schema component, based on the MixLayer schema component. The MixLayer schema component has an array of MixLayerComponent schema components.
However, if I include a $ref to the MixBase schema in the responses section, all the elements are shown correctly.
Request body Example Value section that is missing the 'layers':
{
"mixId": "4f8b533f-7449-4056-92ff-11b1de94d656",
"mixDescription": "SES5M",
"mixScaleName": "MyScale",
"mixRoom": "MixingRoomABC",
"mixProgramId": "ABC-123-ProgramId",
"mixDateTime": "2018-06-07T12:51:25.077Z",
"mixState": "Paused",
"mixNumber": "131",
"mixedByUserName": "john.smith#example.com",
"mixedByFirstName": "John",
"mixedByLastName": "Smith"
}
Responses Example Value section returning the correct list of elements including 'layers':
{
"mixId": "4f8b533f-7449-4056-92ff-11b1de94d656",
"mixDescription": "SES5M",
"mixScaleName": "MyScale",
"mixRoom": "MixingRoomABC",
"mixProgramId": "ABC-123-ProgramId",
"mixDateTime": "2018-06-07T12:51:25.077Z",
"mixState": "Paused",
"mixNumber": "131",
"mixedByUserName": "john.smith#example.com",
"mixedByFirstName": "John",
"mixedByLastName": "Smith",
"layers": [ -- this represents the MixLayer component
{
"unitOfMeasure": "g",
"Components": [ -- this represents the MixLayerComponent correctly
{
"code": "800C",
"description": "800C",
"poured": 204.5,
"density": 1.041
}
]
}
]
}
My requestBody section is defined as: (doesn't show 'layers')
requestBody:
required: true
description: Paint mix information to create
content:
application/json:
schema:
$ref: '#/components/schemas/MixBase'
My responses section is defined as: (and this displays correctly in the Response examples section)
responses:
'200':
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/MixBase'
Here is the definition of the 'layers' within the MixBase schema component (which is the last element in the MixBase definition which is why additionalProperties is set to false): (The formatting might not be correct in stack overflow but the swagger editor doesn't complain so I don't believe the issue is linked to formatting)
layers:
description: Layer related information for components of the mix
type: array
items:
$ref: '#/components/schemas/MixLayer'
readOnly: true
additionalProperties: false
Here is the definition of the MixLayer:
MixLayer:
required:
- Components
type: object
properties:
unitOfMeasure:
description: Unit of volume for the components of the layer
maxLength: 10
type: string
nullable: true
example: g
Components:
description: The components that make up the layer in the mix
type: array
items:
$ref: '#/components/schemas/MixLayerComponent'
readOnly: true
additionalProperties: false
Here is the definition of the MixLayerComponent:
MixLayerComponent:
required:
- code
- density
- poured
type: object
properties:
code:
description: The code associated with the mix component of the layer
maxLength: 25
minLength: 1
type: string
example: 800C
description:
description: The description of the mix component of the layer
maxLength: 120
type: string
nullable: true
example: 800C
poured:
description: >-
The quantity, expressed in the unit of measurement, consumed for the
mix component
type: number
format: double
example: 204.5
density:
description: The density associated with the mix component of the layer
type: number
format: double
example: 1.041
additionalProperties: false
I thought that the "Components" element in the MixLayer component schema might be a reserved keyword in openapi so I changed the references to something else and it still has the same issue.
I thought this issue might be with the online swagger editor (editor.swagger.io) but the same thing occurs in Postman. I also tried browsers Chrome, Edge, and Firefox and they all
have the same issue. I have also tried an XML content type in addition to the JSON I would like to use but still the same issue.
I don't access to post my openapi.json file on stack overflow but I hope this provides enough information.
Any insights anyone has for me to continue a line of investigation would be greatly appreciated.
Thank you for your time in advance,
Dave
layers is defined as a read-only property (readOnly: true) - that's why it doesn't appear in the request body example.

How do I incorporate JSON schema into my OpenAPI file?

Say I have an OpenAPI swagger.yml file that looks like:
openapi: '3.0.2'
info:
title: Simplest ever
version: '1.0'
servers:
- url: https://api.server.test/v1
paths:
/test:
get:
responses:
'200':
description: OK
content:
application/json:
schema:
type: object
properties:
message:
type: string
I prefer to keep the source of truth schema in my schemas/ directory, for example schemas/get.json looks like:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"message": {
"type": "string"
}
}
}
The intent is for the schemas/*.json to used in my backend code base for validation for incoming and outgoing messages. Goal is to have strong API contracts.
What I don't understand is how to build the swagger.yml file using these JSON schema, instead of duplicating the work in YAML which is really tedious and error prone.
In OpenAPI 3.1, you can reference your JSON Schemas directly:
# openapi: 3.1.0
content:
application/json:
schema:
$ref: 'schemas/get.json'
Earlier OpenAPI versions expect that the JSON Schemas be converted to the OpenAPI Schema Object format (which can be represented as both YAML and JSON). The necessary changes include, for example:
removing unsupported keywords: $schema, patternProperties, and others;
replacing type: [<foo>, 'null'] with type: <foo> + nullable: true;
replacing other type arrays type: [type1, type2, ...] with oneOf/anyOf (OAS3) or removing them (OAS2).
json-schema-to-openapi-schema can automate the conversion.
You can try to $ref vanilla JSON Schemas directly from OAS 2.0 and 3.0 definitions, but some tools will error out on unexpected keywords and constructs.

Swagger codegen deserialize dynamic reponse

From my Java backend I'm consuming another backend which I don't manage and it's API definition is not available. I'm creating the OpenAPI definition of it's services and using Swagger Codegen to generate the client.
There is an endpoint which returns a complex object:
{
"total": 151,
"version": 4,
"dynamicItem1": [
"codeDynamicItem1",
293,
63700,
19,
"nameDynamicItem1",
"",
"",
"",
0,
-64
],
"dynamicItem2": [
"codeDynamicItem2",
237,
40000,
478,
"nameDynamicItem2",
"string1",
"string2",
"string3",
0,
0
]
}
In that object the total and version are always there but on the same level there are hundreds of those dynamic items. The key is predictable in the example above but in reality is a sequence of letter and numbers, something like "245df921". The dynamic items are always arrays with the same number of items and in the same expected positions.
To parse that object I'm using additionalProperties beacuse I read that it's the right way to parse hashmaps, but seems like I'm not applying it correctly.
Currently my OpenAPI representation looks like this:
openapi: 3.0.2
info:
version: 1.0.0
title: title
description: description
paths:
/complexObject:
get:
responses:
'200':
description: "OK"
content:
application/json:
schema:
$ref: '#/components/schemas/Object'
components:
schemas:
Object:
type: object
properties:
total:
type: number
example: 151
version:
type: number
example: 4
additionalProperties:
type: array
items:
type: string
nullable: true
Using that implementation the total and version are returned properly but in the response object there is an additionalProperties attribute with null value.
What am I missing?
additionalProperties needs to be on the same level as properties.
Also, since those dynamic array are multi-type (string / integer) you need oneOf to define possible item types.
components:
schemas:
Object:
type: object
properties:
total:
type: number
example: 151
version:
type: number
example: 4
additionalProperties: # <-----
type: array
items:
oneOf: # <-----
- type: string
nullable: true
- type: integer

Swagger/open api 3.0 links not rendered properly [duplicate]

I'm writing an Open API 3.0 spec and trying to get response links to render in Swagger UI v 3.18.3.
Example:
openapi: 3.0.0
info:
title: Test
version: '1.0'
tags:
- name: Artifacts
paths:
/artifacts:
post:
tags:
- Artifacts
operationId: createArtifact
requestBody:
content:
application/octet-stream:
schema:
type: string
format: binary
responses:
201:
description: create
headers:
Location:
schema:
type: string
format: uri
example: /artifacts/100
content:
application/json:
schema:
type: object
properties:
artifactId:
type: integer
format: int64
links:
Read Artifact:
operationId: getArtifact
parameters:
artifact-id: '$response.body#/artifactId'
/artifacts/{artifact-id}:
parameters:
- name: artifact-id
in: path
required: true
schema:
type: integer
format: int64
get:
tags:
- Artifacts
operationId: getArtifact
responses:
200:
description: read
content:
application/octet-stream:
schema:
type: string
format: binary
renders a link like this:
Is this expected? I ask because the operationId is exposed on the UI and parameters is shown as a JSON reference make it seem like something is not displaying properly. I would have expected a hyperlink or something to take me to the appropriate section in the Swagger web page that corresponds to the API being referenced by the link.
Yes this is how Swagger UI currently renders OAS3 links. Rendering of links is one of the things on their OAS3 support backlog:
OAS 3.0 Support Backlog
This is a collection ticket for OAS3 specification features that are not yet supported by Swagger-UI.
...
[ ] Links can't be used to stage another operation
[ ] Link-level servers are not available for executing requests

Resources