From cd348b53f88c18e80bd748ca6e8164de7f2e2805 Mon Sep 17 00:00:00 2001 From: Jay Danielian Date: Sat, 20 Jul 2019 13:50:38 -0400 Subject: [PATCH] Adds anyOf support to requestBody --- test-app/app/controllers/blogs_controller.rb | 12 +++ test-app/app/models/blog.rb | 3 + test-app/config/routes.rb | 2 + test-app/spec/integration/blogs_spec.rb | 27 ++++++ test-app/spec/swagger_helper.rb | 10 +++ test-app/swagger/v1/swagger.json | 91 ++++++++++++++++++++ 6 files changed, 145 insertions(+) diff --git a/test-app/app/controllers/blogs_controller.rb b/test-app/app/controllers/blogs_controller.rb index 8c83a1c..bf922d7 100644 --- a/test-app/app/controllers/blogs_controller.rb +++ b/test-app/app/controllers/blogs_controller.rb @@ -8,6 +8,18 @@ class BlogsController < ApplicationController respond_with @blog end + # POST /blogs/flexible + def flexible_create + + # contrived example to play around with new anyOf and oneOf + # request body definition for 3.0 + blog_params = params.require(:blog).permit(:title, :content, :headline, :text) + + + @blog = Blog.create(blog_params) + respond_with @blog + end + # Put /blogs/1 def upload @blog = Blog.find_by_id(params[:id]) diff --git a/test-app/app/models/blog.rb b/test-app/app/models/blog.rb index ea35f5a..4e96ff7 100644 --- a/test-app/app/models/blog.rb +++ b/test-app/app/models/blog.rb @@ -3,6 +3,9 @@ class Blog < ActiveRecord::Base validates :content, presence: true + alias_attribute :headline, :title + alias_attribute :text, :content + def as_json(_options) { id: id, diff --git a/test-app/config/routes.rb b/test-app/config/routes.rb index be02215..83b9e90 100644 --- a/test-app/config/routes.rb +++ b/test-app/config/routes.rb @@ -1,4 +1,6 @@ TestApp::Application.routes.draw do + + post '/blogs/flexible', to: 'blogs#flexible_create' resources :blogs put '/blogs/:id/upload', to: 'blogs#upload' diff --git a/test-app/spec/integration/blogs_spec.rb b/test-app/spec/integration/blogs_spec.rb index 6a1e951..ded2353 100644 --- a/test-app/spec/integration/blogs_spec.rb +++ b/test-app/spec/integration/blogs_spec.rb @@ -16,6 +16,9 @@ describe 'Blogs API', type: :request, swagger_doc: 'v1/swagger.json' do request_body_json schema: { '$ref' => '#/components/schemas/blog' }, examples: :blog + request_body_text_plain + request_body_xml schema: { '$ref' => '#/components/schemas/blog' } + let(:blog) { { blog: { title: 'foo', content: 'bar' } } } response '201', 'blog created' do @@ -54,6 +57,30 @@ 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' + + request_body_json 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 '$ref' => '#/components/schemas/blog' + run_test! + end + end + end + + path '/blogs/{id}' do diff --git a/test-app/spec/swagger_helper.rb b/test-app/spec/swagger_helper.rb index 2ac0de3..9a864ef 100644 --- a/test-app/spec/swagger_helper.rb +++ b/test-app/spec/swagger_helper.rb @@ -57,6 +57,16 @@ RSpec.configure do |config| thumbnail: { type: 'string' } }, required: %w[id title content thumbnail] + }, + flexible_blog: { + type: 'object', + properties: { + id: { type: 'integer' }, + headline: { type: 'string' }, + text: { type: 'string', nullable: true }, + thumbnail: { type: 'string' } + }, + required: %w[id headline thumbnail] } }, securitySchemes: { diff --git a/test-app/swagger/v1/swagger.json b/test-app/swagger/v1/swagger.json index 6375b5f..a2af55e 100644 --- a/test-app/swagger/v1/swagger.json +++ b/test-app/swagger/v1/swagger.json @@ -105,6 +105,16 @@ "schema": { "$ref": "#/components/schemas/blog" } + }, + "test/plain": { + "schema": { + "type": "string" + } + }, + "application/xml": { + "schema": { + "$ref": "#/components/schemas/blog" + } } } }, @@ -183,6 +193,64 @@ } } }, + "/blogs/flexible": { + "post": { + "summary": "Creates a blog flexible body", + "tags": [ + "Blogs" + ], + "description": "Creates a flexible blog from provided data", + "operationId": "createFlexibleBlog", + "requestBody": { + "required": true, + "content": { + "application/json": { + "examples": { + "flexible_blog": { + "value": { + "blog": { + "headline": "my headline", + "text": "my text" + } + } + } + }, + "schema": { + "oneOf": [ + { + "$ref": "#/components/schemas/blog" + }, + { + "$ref": "#/components/schemas/flexible_blog" + } + ] + } + } + } + }, + "parameters": [ + + ], + "responses": { + "201": { + "description": "flexible blog created", + "content": { + "application/json": { + "example": { + "id": 1, + "title": "my headline", + "content": "my text", + "thumbnail": null + }, + "schema": { + "$ref": "#/components/schemas/blog" + } + } + } + } + } + } + }, "/blogs/{id}": { "get": { "summary": "Retrieves a blog", @@ -336,6 +404,29 @@ "content", "thumbnail" ] + }, + "flexible_blog": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "headline": { + "type": "string" + }, + "text": { + "type": "string", + "nullable": true + }, + "thumbnail": { + "type": "string" + } + }, + "required": [ + "id", + "headline", + "thumbnail" + ] } }, "securitySchemes": {