I've got an OpenAPI schema (edited it to be a minimal working example):
---
openapi: 3.0.0
info:
title: Players API
version: 0.0.1-alpha1
paths:
/players/{id}:
get:
responses:
'200':
description: OK
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/Player'
- type: object
required:
- id
properties:
spec:
type: object
required:
- display_name
components:
schemas:
Player:
type: object
properties:
spec:
$ref: '#/components/schemas/PlayerSpec'
additionalProperties: false
PlayerSpec:
type: object
properties:
display_name:
type: string
description: The name of the player.
example: LeBron
environment:
allOf:
- $ref: '#/components/schemas/PlayerReference'
- required:
- related
description: The environment to which the player belongs.
additionalProperties: false
PlayerReference:
type: object
required:
- id
properties:
id:
type: string
example: 'lebron-23'
and after I run: redoc-cli bundle example.yaml to generate the docs I can see:
(basically id: lebron-23 is there -- i.e., the docs look as expected).
The problem is in order to make it work I had to add example: 'lebron-23' to the definition of a generic PlayerReference component but I'd rather move this example: 'lebron-23' line to this section instead:
environment:
allOf:
- $ref: '#/components/schemas/PlayerReference'
- required:
- related
description: The environment to which the player belongs.
<-------- add id.example here or something
Since environment is an object, an object-level example would look like this:
environment:
allOf:
- $ref: '#/components/schemas/PlayerReference'
- required:
- related
description: The environment to which the player belongs.
example:
id: lebron-23
This example will probably override any examples from allOf subschemas (rather than merge with them), so make sure to include all property values you want to see in this example.
Related
I have redoc-cli installed via npm
$ redoc-cli --version
0.13.20
Now I use it to build docs with the following
openapi: 3.1.0
info:
title: Sample API
version: '1.0'
contact:
email: some#email.com
description: Api description.
tags:
- name: sample tag
description: tag description
servers:
- url: http://localhost:3000
paths:
/int/methods/list:
post:
summary: Sample op
operationId: sample-op
description: Op description.
requestBody:
content:
application/json:
schema:
type: object
properties:
test:
$ref: '#/components/schemas/test'
tags:
- sample tag
components:
schemas:
test1:
title: Test
type: object
properties:
testType:
type: string
testOne:
type: string
test2:
title: Test 2
type: object
properties:
testType:
type: string
testTwo:
type: number
test:
title: Test Polymorph
oneOf:
- $ref: '#/components/schemas/test1'
- $ref: '#/components/schemas/test2'
discriminator:
propertyName: testType
mapping:
ONE: '#/components/schemas/test1'
TWO: '#/components/schemas/test2'
Still attempting to
$ redoc-cli build 04_interface/test.yaml
Prerendering docs
🎉 bundled successfully in: redoc-static.html (1061 KiB) [⏱ 0.179s]
Gives me a result as-if the whole discriminator was missing, i.e.
...instaed of the expected select box, as documented in redocly
I know redocly and redoc-cli are not the same, but redoc-cli used to support discriminators in the past, just at some point it seems to me that it stopped working - or there is some syntax niche I am missing.
So i found what the turning point is. Look at this example.
openapi: 3.1.0
info:
title: Sample API
version: '1.0'
contact:
email: some#email.com
description: Api description.
tags:
- name: sample tag
description: tag description
servers:
- url: http://localhost:3000
paths:
/sample-path:
post:
summary: Sample op
operationId: sample-op
description: Op description.
requestBody:
content:
application/json:
schema:
title: Test
type: object
properties:
prop1:
title: Test Polymorph
oneOf:
- $ref: '#/components/schemas/test1'
- $ref: '#/components/schemas/test2'
discriminator:
propertyName: testType
mapping:
ONE: '#/components/schemas/test1'
TWO: '#/components/schemas/test2'
prop2:
$ref: '#/components/schemas/testPolymorph'
tags:
- sample tag
/another-path:
post:
summary: Another op
operationId: another-op
description: Another op description.
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/testPolymorph'
tags:
- sample tag
components:
schemas:
test1:
title: Test - Variant 1
type: object
properties:
testType:
type: string
testOne:
type: string
test2:
title: Test Variant 2
type: object
properties:
testType:
type: string
testTwo:
type: number
testPolymorph:
title: Test Polymorph
discriminator:
propertyName: testType
mapping:
ONE: '#/components/schemas/test1'
TWO: '#/components/schemas/test2'
oneOf:
- $ref: '#/components/schemas/test1'
- $ref: '#/components/schemas/test2'
This specs yields the following visualization
It seems the discriminator doesnt work for $refs, only if the $ref is on the top schema level.
I started an issue here https://github.com/Redocly/redoc/issues/2252
I'm getting [ERROR] Error resolving ./paths/daas/res_prod_acptd_art_cnts.yaml
java.net.URISyntaxException: Illegal character in opaque part at index 2, org.openapitools.codegen.SpecValidationException -Illegal character in opaque part at index 2 for the following yaml
openapi: 3.1.0
info:
title: test
description: test
# TODO: termsOfService field should be added later
contact:
name: test Support
email: test
version: 0.0.1
license:
name: Copyright
identifier: EPL-2.0
servers:
- url: http://localhost:8080/api
description: Localhost for development purposes
# TODO: Add the security requirments object later
security: []
tags:
- name: DaaS RES Production Service
description: Research workflow Production stage related DaaS Production Service APIs
paths:
# Production Service
/{tenantId}/counts:
$ref: 'paths/daas/res_prod_acptd_art_cnts.yaml'
$ref: 'paths/daas/res_prod_acptd_art_cnts.yaml'
post:
summary: Production Accepted Article Counts
description: API to request counts of production accepted articles by article classification type and other specified global filtering criteria.
tags:
- DaaS RES Production Service
operationId: postProductionAcceptedArticleCounts
requestBody:
description: Contains the parameter combination that must be applied to generate the response
content:
'application/json':
schema:
$ref: '../../components/daas/requestBodies/ReqPayloadProdAcptdArtCnts.yaml'
examples:
example-1:
value:
$ref: '../../components/daas/examples/ReqExProdAcptdArtCnts.yaml'
example-2:
value:
$ref: '../../components/daas/examples/ReqEx2ProdAcptdArtCnts.yaml'
example-3:
value:
$ref: '../../components/daas/examples/ReqEx3ProdAcptdArtCnts.yaml'
example-4:
value:
$ref: '../../components/daas/examples/ReqEx4ProdAcptdArtCnts.yaml'
required: true
responses:
'200':
$ref: '../../components/daas/responses/ResPayloadProdAcptdArtCnts.yaml'
'400':
$ref: '../../components/daas/responses/400BadRequest.yaml'
'401':
$ref: '../../components/daas/responses/401Unauthorized.yaml'
'415':
$ref: '../../components/daas/responses/415UnsupportedMediaType.yaml'
'500':
$ref: '../../components/daas/responses/500InternalServerError.yaml'
parameters:
- name: tenantId
in: path
description: Tenant ID of the tenant of which the caller is invoking the API of.
required: true
schema:
type: string
example: '1001'
I'm trying to use OpenAPI v3 to define models with polymorphism. I've tried the following model definitions and, while they appear to be successfully processed by the Redocly linter, the API documentation generated by Redocly seems to fail to properly document the models.
Here are the OpenAPI document:
openapi: 3.0.3
info:
version: 0.0.3-SNAPSHOT
title: Pet Adaption API
description: |
Adopt a pet!
servers:
- url: 'https://example/pet/api/v1'
description: Pet Adaption API
paths:
/pet_adaptions:
post:
summary: Mark a pet for adaption
description: Mark a pet for adaption
operationId: adopt
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/PetType'
required: true
responses:
200:
description: The pet was marked for adaption
400:
description: The payload was poorly formatted.
500:
description: Unexpected server error.
components:
schemas:
Pet:
type: object
required:
- name
properties:
name:
type: string
description: What goes on their collar.
PetType:
type: object
oneOf:
- $ref: '#/components/schemas/Cat'
- $ref: '#/components/schemas/Dog'
discriminator:
propertyName: type
mapping:
CAT: '#/components/schemas/Cat'
DOG: '#/components/schemas/Dog'
Dog:
type: object
oneOf:
- $ref: '#/components/schemas/LargeDog'
- $ref: '#/components/schemas/SmallDog'
discriminator:
propertyName: size
mapping:
large: '#/components/schemas/LargeDog'
small: '#/components/schemas/SmallDog'
required:
- type
properties:
type:
type: string
description: The type of pet. Always set to `DOG`
LargeDog:
type: object
allOf:
- $ref: '#/components/schemas/Pet'
required:
- size
- floofFactor
properties:
size:
type: string
description: The size of dog. Always set to `large`
floofFactor:
type: integer
description: Floofiness of large dog (1 - 10)
SmallDog:
type: object
allOf:
- $ref: '#/components/schemas/Pet'
required:
- type
- size
- yapFactor
properties:
type:
type: string
description: The type of pet. Always set to `DOG`
size:
type: string
description: The size of dog. Always set to `small`
yapFactor:
type: number
description: Yapiness of small dog (0 - 1.0)
Cat:
type: object
allOf:
- $ref: '#/components/schemas/Pet'
required:
- type
- colour
properties:
type:
type: string
description: The type of pet. Always set to `CAT`
colour:
type: string
description: Colour if the cat's coat
And the following should all be valid examples:
LargeDog
{
"name": "Rex",
"type": "DOG",
"size": "large",
"floofFactor": 3
}
SmallDog
{
"name": "Skip",
"type": "DOG",
"size": "small",
"yapFactor": 0.9
}
Cat
{
"name": "Mr Tinkles",
"type": "CAT",
"colour": "black"
}
The API documentation renders just fine if looking at the CAT example but not when looking at the DOG example.
Have I created an invalid OpenAPI v3 document or is this likely just an issue with Redocly?
Try to pass the discriminator inside size property.
Dog:
type: object
required:
- type
properties:
type:
type: string
description: The type of pet. Always set to `DOG`
size:
type: string
description: The type of pet. Always set to `DOG`
discriminator:
propertyName: size
mapping:
large: '#/components/schemas/LargeDog'
small: '#/components/schemas/SmallDog'
oneOf:
- $ref: '#/components/schemas/LargeDog'
- $ref: '#/components/schemas/SmallDog'
enter image description here
Let's say I have some simple Order > OrderLines > Product Data Model in an OpenAPI document.
The Components part would look like this:
components:
schemas:
Order:
required:
- orderId
properties:
orderId:
type: integer
orderlines:
type: array
items:
$ref: '#/components/schemas/OrderLine'
OrderLine:
required:
- orderLineId
- product
- price
properties:
orderLineId:
type: integer
product:
$ref: '#/components/schemas/Product'
price:
type: integer
Product:
required:
- productId
- name
x-keys:
- productId
properties:
productId:
type: integer
name:
type: string
When building a path to define an api to get a specific OrderLine on an Order, this would look like this:
paths:
/orders/{orderId}/orderlines/{orderLineId}:
get:
operationId: getOrderLine
parameters:
- in: path
name: orderId
schema:
type: integer
required: true
- in: path
name: orderLineId
schema:
type: integer
required: true
Now, the defined orderId parameters actually refers to the orderId property of the Order Component. And the same goes for parameter orderLineId which refers to the orderLineId property of Component OrderLine.
So is it possible to actually refer to these properties in the parameter definition instead of duplicating the type information of the properties?
I mean is it somehow possible to do something like this:
paths:
/orders/{orderId}/orderlines/{orderLineId}:
get:
operationId: getOrderLine
parameters:
- in: path
name: orderId
$ref: #components/schemas/Order/properties/orderId
required: true
- in: path
name: orderLineId
$ref: #components/schemas/OrderLine/properties/orderLineId
required: true
First of all, always add type: object to your object definitions; the properties keyword alone is not enough to indicate the object type. The type is not inferred from other keywords, and no type actually means "any type".
As for your question - sure, it's possible to $ref individual property definitions. Your example is almost correct, you just need to:
Put the $ref inside the parameter schema.
Replace #components with #/components.
Enclose the reference values (#/components/...) in quotes to prevent them from being parsed as YAML comments.
paths:
/orders/{orderId}/orderlines/{orderLineId}:
get:
operationId: getOrderLine
parameters:
- in: path
name: orderId
schema:
$ref: '#/components/schemas/Order/properties/orderId'
required: true
- in: path
name: orderLineId
schema:
$ref: '#/components/schemas/OrderLine/properties/orderLineId'
required: true
However, referencing property definitions is uncommon, and some tools may have problems handling such references. It's best to define separate schemas for all definitions you want to $ref:
components:
schemas:
OrderId: # <-------
type: integer
OrderLineId: # <-------
type: integer
Order:
type: object
required:
- orderId
properties:
orderId:
$ref: '#/components/schemas/OrderId' # <-------
...
OrderLine:
type: object
required:
- orderLineId
- product
- price
properties:
orderLineId:
$ref: '#/components/schemas/OrderLineId' # <-------
...
paths:
/orders/{orderId}/orderlines/{orderLineId}:
get:
operationId: getOrderLine
parameters:
- in: path
name: orderId
schema:
$ref: '#/components/schemas/OrderId' # <-------
required: true
- in: path
name: orderLineId
schema:
$ref: '#/components/schemas/OrderLineId' # <-------
required: true
I've take the allOf examples in https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#models-with-composition, and applied them to parameters schema and responses schema. My allOf parameters and responses, however, show as undefined. When just using Pet instead of Cat, it works fine. Please let me know how to use Swagger's allOf
swagger: '2.0'
# This is your document metadata
info:
version: "0.0.0"
title: <enter your title>
# Describe your paths here
paths:
/test1:
# This is a HTTP operation
post:
description: bla bla
parameters:
- name: Pet
required: true
in: body
description: The Pet.
schema:
$ref: '#/definitions/Pet'
# Expected responses for this operation:
responses:
# Response code
200:
description: Successful response
schema:
$ref: '#/definitions/Pet'
/test2:
# This is a HTTP operation
post:
description: bla bla
parameters:
- name: Cat
required: true
in: body
description: The cat.
schema:
$ref: '#/definitions/Cat'
# Expected responses for this operation:
responses:
# Response code
200:
description: Successful response
schema:
$ref: '#/definitions/Cat'
definitions:
Pet:
type: object
discriminator: petType
properties:
name:
type: string
petType:
type: string
required:
- name
- petType
Cat:
description: A representation of a cat
allOf:
- $ref: '#/definitions/Pet'
- type: object
properties:
huntingSkill:
type: string
description: The measured skill for hunting
default: lazy
enum:
- clueless
- lazy
- adventurous
- aggressive
required:
- huntingSkill
A type field is missing in Cat Definitions Object and therefore swagger-editor shows undefined.
Add type: object as follow can fix it:
Cat:
type: object
description: A representation of a cat
allOf: