Swagger codegen deserialize dynamic reponse - swagger

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

Related

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.

swagger codegen missing attributes with allOf

We are using the latest swagger-codegen-cli (currently v2.4.28) to generate a python client from a swagger yaml file. We use allOf throughout our specification to re-use definitions across multiple types of response objects. When generating a python client we notice that model classes generated seem to be missing any attributes defined in the first allOf reference.
The specification is valid, and there are no errors or warnings generated that would indicate a problem so I am not sure if this is a bug or if we've misunderstood the intended usage.
Here is a minimal example that illustrates the problem.
swagger: '2.0'
info:
version: "0.1.0"
title: Sample
host: localhost:8080
schemes:
- https
basePath: /sample/v1
paths:
/info:
get:
summary: Get Info
operationId: getInfo
produces:
- application/json
tags:
- Info
responses:
200:
description: Information Response
schema:
$ref: "#/definitions/InfoResponse"
default:
description: Unexpected error
definitions:
InfoResponse:
type: object
allOf:
- $ref: "#/definitions/Part1"
- $ref: "#/definitions/Part2"
- $ref: "#/definitions/Part3"
Part1:
type: object
properties:
a:
type: integer
b:
type: integer
Part2:
type: object
properties:
c:
type: string
d:
type: string
Part3:
type: object
properties:
e:
type: string
f:
type: string
We use the following command to generate the python client.
java -jar swagger-codegen-cli-2.4.28.jar generate -l python -i api-specification.yaml -o codegen
The python model class for the InfoResponse object has the following swagger_types and attribute_map values.
swagger_types = {
'c': 'str',
'd': 'str',
'e': 'str',
'f': 'str'
}
attribute_map = {
'c': 'c',
'd': 'd',
'e': 'e',
'f': 'f'
}
As you can see, the two attributes from the Part1 reference are missing (i.e., "a", and "b"). If I reorder the references so that Part2 is first then "c" and "d" go missing and "a" and "b" are present. Like this:
InfoResponse:
type: object
allOf:
- $ref: "#/definitions/Part2"
- $ref: "#/definitions/Part1"
- $ref: "#/definitions/Part3"
It would appear as though the first reference in the list is always ignored. Is this a bug, a template problem, are the definitions not specified correctly, or am I not understanding how this is supposed to work?

Why did a schema inherit examples of array items from its subschema?

OpenAPI 3.0.0, Swagger online editor.
I composed subschemas via the allOf discriminator and set the example field for a resulting schema. Swagger UI, however, didn't provide the example as-is.
The schema contained an array originating from the subschema. The array inherited example items from the subschema and extended the list with the examples from the schema.
Example
Let's say we have two schemas:
Cats:
type: object
properties:
cats:
type: array
items:
type: object
properties:
fluffiness:
type: integer
names:
type: string
example:
cats:
- fluffiness: 9
names: "Felix"
- fluffiness: 10
names: "Neko"
FluffiestCats:
allOf:
- $ref: '#/components/schemas/Cats'
- type: object
properties:
date:
type: string
format: "date"
example:
cats:
- fluffiness: 10
names: "Luna"
- fluffiness: 10
names: "Meowie"
date: "17-01-2021"
Responding to some request, the API retrieves the fluffiest cats, referencing #/components/schemas/FluffiestCats/. Swagger UI generates the following response example.
{
"cats": [
{
"fluffiness": 9,
"names": "Felix"
},
{
"fluffiness": 10,
"names": "Neko"
},
{
"fluffiness": 10,
"names": "Luna"
},
{
"fluffiness": 10,
"names": "Meowie"
}
],
"date": "17-01-2021"
}
Swagger UI takes two examples from the subschema example items. The provided example doesn't override the subschema example.
Does this behaviour contradict the specification? According to the description, it seems the Schema Object's example field doesn't imply override, in contrast to the Parameter Object's example field.
How can I override the subschema example? Or do I have to recreate the schema without using the allOf?
References
How to reference array item examples in OpenAPI 3?
OpenAPI 3.0.0 specification
It was an issue with Swagger UI.
Fixed in Swagger UI 4.5.0 and Swagger Editor 4.0.7.

How to hide swagger ref attributes in specific paths?

I have this structure in swagger documentation:
FunctionTitle:
type: object
required:
- funcId
- czechName
- priority
properties:
funcId:
type: number
format: id
example: 1226
czechName:
type: string
example: Guvernér
priority:
type: number
example: 21
org:
$ref: '#/definitions/Organ'
funcType:
$ref: '#/definitions/FunctionType'
In some path I want to return this structure, but without properties org and funcType. So my response should be something like that:
{
"funcId" : 1226,
"czechName" : "Guvernér",
priority: 21
}
I didnt find how to choose not to return properties org and funcType. I know I can create another model for it, but it will be better for me to only hide properties as I want and not to create another model. Here is example of my path:
/periods:
get:
tags:
- developers & users
summary: Periods
operationId: periods
description: |
By passing in the appropriate options, you can search for
available inventory in the system
produces:
- application/json
responses:
200:
description: search matching criteria
schema:
type: object
properties:
periods:
type: array
items:
$ref: '#/definitions/FunctionTitle'
400:
description: bad input parameter
Thank you for your answers!

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

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.

Resources