OpenAPI multiple types inside an array - swagger

I'm having trouble defining a reusable schema component using OpenAPI 3 which would allow for an array that contains multiple types. Each item type inherits from the same parent class but has specific child properties. This seems to work alright in the model view on SwaggerHub but the example view doesn't show the data correctly.
TLDR; Is there a way to define an array containing different object types in OpenAPI 3?
Response:
allOf:
- $ref: '#/components/schemas/BaseResponse'
- type: object
title: A full response
required:
- things
properties:
things:
type: array
items:
anyOf:
- $ref: '#/components/schemas/ItemOne'
- $ref: '#/components/schemas/ItemTwo'
- $ref: '#/components/schemas/ItemThree'

Your spec is correct. It's just that example rendering for oneOf and anyOf schemas is not yet supported in Swagger UI. You can track this issue for status updates:
Multiple responses using oneOf attribute do not appear in UI
The workaround is to manually add an example alongside the oneOf/anyOf schema or to the parent schema:
things:
type: array
items:
anyOf:
- $ref: '#/components/schemas/ItemOne'
- $ref: '#/components/schemas/ItemTwo'
- $ref: '#/components/schemas/ItemThree'
# Note that array example is on the same
# level as `type: array`
example:
- foo: bar # Example of ItemOne
baz: qux
- "Hello, world" # Example of ItemTwo
- [4, 8, 15, 16, 23, 42] # Example of ItemThree

Related

schema array in swagger

I have some problem with swagger. When I think I understand how it works, there's always something that doesn't work
What's wrong in thoses line
responses:
'200':
allOf:
- $ref: '../index.yaml#/components/responses/200Ok'
content:
application/json:
schema:
allOf:
- $ref: '../index.yaml#/components/schemas/Pagination'
properties:
data:
type: array
items:
schema:
$ref: '../index.yaml#/components/schemas/Client'
The "data" property should be an array of the schema type given in the $ref, but this is the result
"data": [
null
]
EDIT
Ok, it seems that the right way is tu put the $ref directly under the items key, my problem was the use of a reserved key "status"
So, how can I use a reserved key in a object schema?
EDIT
in my Client schema I put the property status two times, I didn't see that it was already there, so when I changed the property name it worked and I was thinking that maybe "status" was a reserved keyword.
You are almost there. There are two issues:
1) You can't have allOf directly under a response code. You can $ref the whole response definition though.
2) You don't need schema under items.
Also, while putting allOf alongside other keywords is perfectly fine, some tools may like it better if all schemas being combined are listed inside allOf.
Try this version:
responses:
'200':
description: OK
content:
application/json:
schema:
allOf:
- $ref: '../index.yaml#/components/schemas/Pagination'
- properties:
data:
type: array
items:
$ref: '../index.yaml#/components/schemas/Client'

How to exclude property from swagger definition

I'm using Swagger online editor. I create some model in definition
Object:
type: object
properties:
id:
type: integer
format: int32
name:
type: string
some_variable_to_exclude:
type: string
This is complete model and i use it in different responses. But in one of they i want my model dont present property "some_variable_to_exclude". How can i exclude it ? Is it possible ?
Okay, maybe not exclude, maybe some comment near property, but only for that response.
In order to extend the Swagger Schema with custom objects, the field must begin with x-
See more here: http://swagger.io/specification/#vendorExtensions
For example, swagger-node uses x-swagger-router-controller to specify which controller to use for a particular API path. But you can use it for whatever you need, e.g., x-custom-property
Create another definition without field you don't need
Create definition without field you don't need, like
components:
schemas:
Object:
type: object
properties:
id:
type: integer
format: int32
name:
type: string
then, on describe new full scheme, write this:
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/Object'
- properties:
some_variable_to_exclude:
type: string

Using different Swagger Models properties for collection/detail request/response

I'm beginner of Swagger, and I'm trying to define endpoints which have:
Some read-only properties that isn't allowed in request but show in response
Some white-only properties and hidden that allowed in request but not show in response
Some properties only on collection level at /resources, but some other additional details on /resources/resource-id
What I'm doing is defining the following models:
ResourceBaseModel: this saves all the shared properties of all
ResourceBaseModel:
type: object
properties:
shared_properties:
type: string
ResourceCollectionResponse: this is wrapping the response additional properties
ResourceCollectionResponse:
type: array
items:
type: object
allOf:
- $ref: ResourceBaseModel
- type: object
properties:
collection_normal_properties:
type: string
collection_read_only_properties:
type: string
readOnly: true
ResourceDetailResponse: this is adding different properties for response
ResourceDetailResponse:
type: object
allOf:
- $ref: ResourceBaseModel
- type: object
properties:
detail_normal_properties:
type: string
detail_read_only_properties:
type: string
readOnly: true
ResourceRequest: same, add additional and write-only properties
ResourceRequest:
type: object
allOf:
- $ref: ResourceBaseModel
- type: object
properties:
request_write_only_properties:
type: string
This is making every model defined 4 times and I feel it's not efficient.
So here are my questions:
I saw there is a discriminator in Swagger Spec. Should I use this with "allOf" of these extended models? From result, using of not using this discriminator, the result looks the same as long as "allOf" used.
the "readOnly", if defined in base level, still shows in Swagger UI and needs special handling or filtering when using or generating docs. The demo data in request is also showing these readOnly properties in Swagger UI request (but only the model added a label of "read-only"). Is there any better solution besides what I'm trying.
the "white-only", as far as I know, is not supported. Is defining a new model the only way?
I wonder if there will be one day I can define only one model to describe all of the models, or do you think an innovative language that can compile to Swagger YAML can benefit the whole community? Like how Sass/LESS builds CSS?
Thanks for your help and insightes!
OpenAPI 3.0.x supports writeOnly as well as readOnly schema properties. This should allow you to simplify your models, the allOf / discriminator should not be necessary.

Can I specify the response directly in Swagger 2.0?

I am defining my response as per:
responses:
200:
description: 'An authProvider object'
schema:
type: 'array'
items:
$ref: '#/definitions/AuthProvider'
Is it possible for me to directly attach another field or 2 in the response? I would like to add something that I don't want to put into AuthProvider
Whenever $ref is used, it's basically using JSON Reference. By definition (see linked spec), anything defined within the same object as the reference itself is ignored. As such, it is not possible to directly add additional properties alongside with the $ref definition.
That said, you can use composition to 'combine' two objects into one. This is done using the allOf JSON Schema directive. A simple example for such a definition would look like this:
allOf:
-
$ref: "..."
-
properties:
property1:
type: "string"
property2:
type: "boolean"
Note 1: The various Swagger tools out there may not fully support composition at the moment.
Note 2: As always, it's normally better to externalize the definition (even if used only once) rather than being defined inline.

Inheritance in swagger-editor throwing an error

Using swagger editor and getting a validation error when I try to inherit from a model contains an array. I am assuming that my definition is screwed up as I am new to swagger. But I do know that there is still work to be done to support swagger 2.0 in the editor. Not looking to point out a bug or deficiency in the editor, just want to know if my schema is valid.
This works in the editor (from simple petstore example):
definitions:
pet:
properties:
name:
type: string
newPet:
allOf:
- $ref: '#/definitions/pet'
However I want to define pet as an array:
definitions:
pet:
type: array
items:
type: string
newPet:
allOf:
- $ref: '#/definitions/pet'
Technically speaking, that's not inheritance, that's composition. There's no hierarchical relation between newPet and pet. For a inheritance, the definitions must both be objects, and there has to be a discriminator definition.
As far as composition goes, that looks like a valid definition.
Here is an example: https://github.com/OAI/OpenAPI-Specification/blob/master/examples/v2.0/yaml/petstore-expanded.yaml
So it looks like this:
definitions:
Pet:
allOf:
- $ref: '#/definitions/NewPet'
required:
- id
properties:
id:
type: integer
format: int64
NewPet:
required:
- name
properties:
name:
type: string
tag:
type: string

Resources