add support for oneOf anyOf allOf

This commit is contained in:
Greg Myers 2020-04-05 00:36:25 +01:00
parent d644a91da5
commit 965f14406f
4 changed files with 100 additions and 18 deletions

View File

@ -18,7 +18,7 @@ Once you have an API that can describe itself in Swagger, you've opened the trea
|Rswag Version|Swagger (OpenAPI) Spec.|swagger-ui|
|----------|----------|----------|
|[master](https://github.com/rswag/rswag/tree/master)|3.0|3.18.2|
|[master](https://github.com/rswag/rswag/tree/master)|3.0.3|3.23.11|
|[2.2.0](https://github.com/rswag/rswag/tree/2.2.0)|2.0|3.18.2|
|[1.6.0](https://github.com/rswag/rswag/tree/1.6.0)|2.0|2.2.5|
@ -59,6 +59,7 @@ Once you have an API that can describe itself in Swagger, you've opened the trea
```
3. Create an integration spec to describe and test your API.
There is also a generator which can help get you started `rails generate rspec:swagger API::MyController`
```ruby
# spec/integration/blogs_spec.rb
@ -71,7 +72,7 @@ Once you have an API that can describe itself in Swagger, you've opened the trea
post 'Creates a blog' do
tags 'Blogs'
consumes 'application/json'
request_body_json schema: {
parameter name: :blog, in: :body, schema: {
type: :object,
properties: {
title: { type: :string },
@ -97,7 +98,7 @@ Once you have an API that can describe itself in Swagger, you've opened the trea
get 'Retrieves a blog' do
tags 'Blogs'
produces 'application/json', 'application/xml'
parameter name: :id, :in => :path, :type => :string
parameter name: :id, in: :path, type: :string
response '200', 'blog found' do
schema type: :object,
@ -126,8 +127,6 @@ Once you have an API that can describe itself in Swagger, you've opened the trea
end
```
There is also a generator which can help get you started `rails generate rspec:swagger API::MyController`
4. Generate the Swagger JSON file(s)
@ -137,6 +136,11 @@ Once you have an API that can describe itself in Swagger, you've opened the trea
This common command is also aliased as `rake rswag`.
Or if you installed your gems separately:
```
RAILS_ENV=test rails rswag
```
5. Spin up your app and check out the awesome, auto-generated docs at _/api-docs_!
## The rspec DSL ##
@ -197,14 +201,13 @@ describe 'Blogs API' do
end
```
### Support for anyOf or AllOf schemas ###
### Support for oneOf, anyOf or AllOf schemas ###
Open API 3.0 now supports more flexible schema validation with the ```anyOf``` and ```allOf``` directives. rswag will handle these definitions and validate them properly.
Open API 3.0 now supports more flexible schema validation with the ```oneOf```, ```anyOf``` and ```allOf``` directives. rswag will handle these definitions and validate them properly.
Notice the ```schema``` inside the ```response``` section. Placing a ```schema``` method inside the response will validate (and fail the tests)
if during the integration test run the endpoint response does not match the response schema. This test validation can handle
anyOf and allOf as well. See below:
if during the integration test run the endpoint response does not match the response schema. This test validation can handle anyOf and allOf as well. See below:
```ruby
@ -216,18 +219,15 @@ anyOf and allOf as well. See below:
consumes 'application/json'
produces 'application/json'
request_body_json schema: {
:oneOf => [
parameter name: :blog, in: :body, schema: {
oneOf: [
{ '$ref' => '#/components/schemas/blog' },
{ '$ref' => '#/components/schemas/flexible_blog' }
]
},
examples: :flexible_blog
let(:flexible_blog) { { blog: { headline: 'my headline', text: 'my text' } } }
}
response '201', 'flexible blog created' do
schema :oneOf => [{ '$ref' => '#/components/schemas/blog' }, { '$ref' => '#/components/schemas/flexible_blog' }]
schema oneOf: [{ '$ref' => '#/components/schemas/blog' }, { '$ref' => '#/components/schemas/flexible_blog' }]
run_test!
end
end

View File

@ -49,6 +49,30 @@ RSpec.describe 'Blogs API', type: :request, swagger_doc: 'v1/swagger.json' do
end
end
path '/blogs/flexible' do
post 'Creates a blog flexible body' do
tags 'Blogs'
description 'Creates a flexible blog from provided data'
operationId 'createFlexibleBlog'
consumes 'application/json'
produces 'application/json'
parameter name: :flexible_blog, in: :body, schema: {
oneOf: [
{ '$ref' => '#/definitions/blog' },
{ '$ref' => '#/definitions/flexible_blog' }
]
}
let(:flexible_blog) { { blog: { headline: 'my headline', text: 'my text' } } }
response '201', 'flexible blog created' do
schema oneOf: [{ '$ref' => '#/definitions/blog' }, { '$ref' => '#/definitions/flexible_blog' }]
run_test!
end
end
end
path '/blogs/{id}' do
parameter name: :id, in: :path, type: :string

View File

@ -52,9 +52,19 @@ RSpec.configure do |config|
id: { type: 'integer' },
title: { type: 'string' },
content: { type: 'string', 'x-nullable': true },
thumbnail: { type: 'string'}
thumbnail: { type: 'string', 'x-nullable': true}
},
required: [ 'id', 'title', 'content', 'thumbnail' ]
required: [ 'id', 'title' ]
},
flexible_blog: {
type: 'object',
properties: {
id: { type: 'integer' },
headline: { type: 'string' },
text: { type: 'string', nullable: true },
thumbnail: { type: 'string', nullable: true }
},
required: ['id', 'headline']
}
},
securityDefinitions: {

View File

@ -155,6 +155,54 @@
}
}
},
"/blogs/flexible": {
"post": {
"summary": "Creates a blog flexible body",
"tags": [
"Blogs"
],
"description": "Creates a flexible blog from provided data",
"operationId": "createFlexibleBlog",
"parameters": [
],
"responses": {
"201": {
"description": "flexible blog created",
"content": {
"application/json": {
"schema": {
"oneOf": [
{
"$ref": "#/components/schemas/blog"
},
{
"$ref": "#/components/schemas/flexible_blog"
}
]
}
}
}
}
},
"requestBody": {
"content": {
"application/json": {
"schema": {
"oneOf": [
{
"$ref": "#/components/schemas/blog"
},
{
"$ref": "#/components/schemas/flexible_blog"
}
]
}
}
}
}
}
},
"/blogs/{id}": {
"parameters": [
{