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?
Related
I got the following YAML, when I try this, in https://editor.swagger.io/ I'm getting "$ref values must be RFC3986-compliant percent-encoded URIs" error when I use [ and ] brackets, I tried encoding them but the response schema is not getting recognized, saying the reference is missing. Any help on what can be the issue in this scenario?
swagger: "2.0"
info:
title: test
version: "1.0"
paths:
/api/TestCustomer:
post:
consumes:
- application/json
- text/json
produces:
- application/json
- text/json
parameters:
- name: request
in: body
required: true
schema:
$ref: '#/definitions/UpdateTestCustomerRequest'
responses:
'201':
description: Test Response
schema:
$ref: '#/definitions/Result[UpdateTestCustomerResponse]' ***This line results in a error "$ref values must be RFC3986-compliant percent-encoded URIs"
definitions:
UpdateTestCustomerRequest:
type: object
properties:
CustomerId:
type: string
UpdatedBy:
type: string
Result[UpdateTestCustomerResponse]:
type: object
properties:
Status:
format: int32
enum:
- 201
type: integer
Response:
$ref: '#/definitions/UpdateTestCustomerResponse'
UpdateTestCustomerResponse:
type: object
properties:
CustomerId:
type: string
In OpenAPI 2.0, if some schema names contain special characters, they must be URL-encoded in the $ref paths. Replace [ with %5B and ] with %5D in the $ref path, e.g.:
# Incorrect
$ref: '#/definitions/Result[UpdateTestCustomerResponse]'
# Correct
$ref: '#/definitions/Result%5BUpdateTestCustomerResponse%5D'
Or better yet, don't use special characters in schema names.
If/when you migrate to OpenAPI 3, you'll have to remove the [ ] characters from schema names because the newer versions only allow A..Z a..z 0..9 _ . - in schema names.
The following YAML:
openapi: 3.0.0
info:
title: test
version: 1.0.0
paths:
/test:
get:
summary: test
responses:
'200':
description: Test
content:
application/json:
schema:
oneOf:
- allOf:
- type: object
properties:
firstA:
type: string
- type: object
properties:
firstB:
type: string
- allOf:
- type: object
properties:
secondA:
type: string
- type: object
properties:
secondB:
type: string
Does not render at all in the swagger editor.
In ReDoc it also fails to render properly:
If nesting multiple allOf instances directly inside of oneOf is invalid, how could I achieve the same result with a valid spec?
ReDoc author here.
It is a ReDoc bug. Your spec is valid.
It has been already fixed and will be available in 2.0.0-alpha.40.
I'm writing a Swagger definition on swaggerhub. There's an option to share models among multiple Swaggers. After swaggers are complete there's an option to download resolved Swagger with the linked definitions imported.
My problem is that this resolved download adds a example node to the models which for whatever reason overrides every attribute when we copy this new Swagger in editor again.
Suppose we have following sample
---
swagger: "2.0"
info:
description: ""
version: 1.0.0
title: title
host: "example.com"
basePath: /
schemes:
- http
consumes:
- application/json
produces:
- application/json
paths:
/test-service:
post:
tags:
- test-service
operationId: test-service
parameters:
- in: body
name: body
description: body
required: true
schema:
$ref: '#/definitions/A'
responses:
201:
description: success
schema:
$ref: '#/definitions/A'
definitions:
A:
type: object
properties:
a1:
type: string
a2:
type: string
Following is how it's displayed in the Swagger UI,
This is correct way, however when I there's an example node in the model A, only example attributes are displayed in the UI,
Here's the change that that I'm referring to
A:
type: object
properties:
a1:
type: string
a2:
type: string
example:
ex1: Hello
ex2: World
Now, if I import this change in the editor, only attributes ex1 and ex2 and actual attributes a1 and a2 are missing.
Problem is exacerbate when we have inheritance.
What happens is whichever lowest node in hierarchy has example attribute only attributes listed in that are shown in the UI, rather than showing all attributes
Here's a sample wi
Now lets introduce example attribute in C. After addition of example attribute at any level all other attributes are ignored.
Here's the link to example attribute documentation https://swagger.io/docs/specification/2-0/adding-examples/.
There's no description of this weird behavior.
That's how example works. Quoting the OpenAPI 2.0 Specification:
A free-form ... example of an instance for this schema.
That is, example is an example for the entire schema. That's why a schema-level example is displayed as is. It overrides any property-level examples, and won't automatically include properties that aren't included in the example.
In your last example with allOf, the schema for A is equivalent to
definitions:
A:
type: object
properties:
a1:
type: string
a2:
type: string
b1:
type: string
b2:
type: string
c1:
type: string
c2:
type: string
example:
ex1: Hello
ex2: world
which again is why the schema-level example from C overrides everything else.
You might want to use property-level examples instead:
definitions:
A:
type: object
properties:
a1:
type: string
example: Hello # <---
a2:
type: string
example: world # <---
I have a swagger file for an API that is going to reside inside IBM API Connect. I typed it out from an IBM tutorial, and I was trying to replicate what the instructor was doing(he did not provide any source files, so I had to type it out).
The tutorial is available here: https://www.youtube.com/watch?v=hCvUYd67rbI
The guy is copy-pasting the swagger file inside the APIConnect local designer around 21:40.
I took the swagger file and put it into http://editor.swagger.io/ and I got a bunch of parser errors:
Errors
Hide
Parser error duplicated mapping key
Jump to line 31
Semantic error at definitions.shipping.properties.xyz.type
Sibling values are not allowed alongside $refs
Jump to line 86
Semantic error at definitions.shipping.properties.cek.type
Sibling values are not allowed alongside $refs
Jump to line 89
I did some digging, and I did not find a lot of resources for my kind of problem. I double-checked if I typed it out correctly from the tutorial. Maybe it has something to do with an older version of API Connect being used in ths tutorial.
Thanks in advance for anyone who can help.
EDIT:
Sorry, it was a bit late so I was tired, I am adding the source code in the yaml file:
info:
x-ibm-name: logistics
title: logistics
version: 1.0.0
schemes:
- https
basePath: /logistics
consumes:
- application/json
produces:
- application/json
securityDefinitions:
clientIdHeader:
type: apiKey
in: header
name: X-IBM-Client-Id
security:
- clientdHeader: []
x-ibm-configuration:
testable: true
enforced: true
cors:
enabled: true
gateway: datapower-gateway
catalogs:
apic-dev:
properties:
runtime-url: $(TARGET_URL)
properties:
shipping_svc_url:
value: 'http://shipping.think.ibm:5000/calculate'
description: Location of the shipping calculator service
encoded: false
paths:
/shipping:
get:
responses:
'200':
description: 200 OK
schema:
$ref: '#/definitions/shipping'
summary: Calculate shipping costs to a destination zip code
operationId: shipping.calc
parameters:
- name: zip
type: string
required: true
in: query
description: Destination zip code.
/stores:
get:
responses:
'200':
description: 200 OK
schema:
$ref: '#/definitions/store_location'
tags:
- stores
summary: Locate store near zip code
operationId: get.stores
parameters:
- name: zip
type: string
required: true
in: query
definitions:
rates:
properties:
next_day:
type: string
example: '20.00'
two_day:
type: string
example: '17.00'
ground:
type: string
example: '8.00'
required:
- two_day
- next_day
- ground
shipping:
properties:
xyz:
type: string
$ref: '#/definitions/rates'
cek:
type: string
$ref: '#/definitions/rates'
required:
- xyz
- cek
store_location:
properties:
google_maps_link:
type: string
example: 'https://www.google.com/maps?q=34.1030032,-118.4104684'
required:
- google_maps_link
There's typo: securityDefinitions defines clientIdHeader, but security refers to clientdHeader (..ntd.. instead of ..enId..).
"Sibling values are not allowed alongside $refs" is not a syntax error, but rather a warning. It's caused by this line:
definitions:
rates:
properties:
...
shipping:
properties:
xyz:
type: string # <---------------
$ref: '#/definitions/rates'
$ref is a JSON Reference, it works by replacing itself and all sibling attributes with the content the $ref is pointing at. So, the type attribute and any other attributes alongside $ref will be ignored. The warning informs you about this in case there are important attributes alongside $ref -- these attributes need to be moved into the $ref'erenced schema to have effect.
That said, xyz being type: string does not make sense, because rates is an object and not a string.
You should also consider adding type: object to the rates, shipping and store_location definitions to indicate that they are objects.
Using swagger-editor and swagger-ui to build a swagger2.0 specification in YAML.
I have split the spec into a client.yml and several model.yml files.
Each model defines some parameters or response objects.
When I open client.yml in the editor, it will load the models into the client using $ref:
However, there appears to be a problem if an object in one of the model files tries to reference an object in another model file.
I have tried absolute and relative paths to no avail. I always get an error, like:
"Reference could not be resolved: /models/basemodel.yml#/BasicObject"
path: Array [10]
error: "Cannot use 'in' operator to search for 'BasicObject' in undefined"
level: 900
type: "Swagger Error"
description: "Reference could not be resolved: /models/basemodel.yml#/BasicObject"
lineNumber: -1
The SimplerObject is identical and works fine. This references a CopyOfBasicObject in the same file. The AdvancedObject tries to reference the BasicObject in a different model file.
The goal is to not copy the definition of BasicObject but refer to it.
It is often necessary to clear the browser cache and reload the page before the editor read the new version of the model file.
The files I used to test this are included. I have converted to a single file as stackoverflow editor is not rendering the yaml very well.
swagger: '2.0'
info:
title: test indirect reference
description: etc
version: "Draft 0.1.1"
host: example.com
basePath: /
produces:
- application/json
paths:
/advancedObjects:
post:
summary: |
post an object.
parameters:
- name: advancedObject
in: body
required: true
schema:
type: array
items:
$ref: '/models/model.yml#/AdvancedObject' # This doeesn't work
#$ref: '/models/model.yml#/SimplerObject' # This works fine
#$ref: '/models/basemodel.yml#/BasicObject' # This works fine
responses:
200:
description: OK
definitions:
AdvancedObject: #move to /models/model.yml
type: object
description: Contains a reference to a basic object
properties:
base:
$ref: '/models/basemodel.yml#/BasicObject'
advanced:
type: array
items:
type: number
CopyOfBasicObject: # move to /models/model.yml
type: object
description: Another simple object
properties:
id:
type: number
SimplerObject: # move to /models/model.yml
type: object
description: Same as AdvanceObject but without reference to another file
properties:
base:
$ref: '#/CopyOfBasicObject'
advanced:
type: array
items:
type: number
BasicObject: # move to /models/basemodel.yml
type: object
description: A simple object
properties:
id:
type: number