I have a rails 6 project and am trying to document the API using swagger and the rswag gem.
My rspec spec for the controller is as follows:
require 'swagger_helper'
RSpec.describe 'api/v1/books', type: :request do
let!(:book1) { create :book }
let!(:book2) { create :book }
let!( :account) { create :account }
let!(:access_token) { Auth::JsonWebToken.encode(account_id: account.id) }
let!(:Authorization) { access_token.to_s }
path '/api/v1/books' do
get('list books') do
parameter name: :Authorization, in: :header, type: :string
produces 'application/json'
response(200, 'successful') do
after do |example|
example.metadata[:response][:content] = {
'application/json' => {
example: JSON.parse(response.body, symbolize_names: true)
}
}
end
run_test! do |response|
data = JSON.parse(response.body)
expect(data['books'].count).to eq(2)
end
end
end
end
path '/api/v1/books/{id}' do
parameter name: 'id', in: :path, type: :string, description: 'id'
parameter name: :Authorization, in: :header, type: :string
get('show book') do
response(200, 'successful') do
let(:id) { book1.id }
after do |example|
example.metadata[:response][:content] = {
'application/json' => {
example: JSON.parse(response.body, symbolize_names: true)
}
}
end
run_test! do |response|
data = JSON.parse(response.body)
expect(data['id']).to eq(book1['id'])
end
end
end
end
path 'api/v1/books' do
post 'Creates a book' do
consumes 'application/json'
parameter name: :book, in: :body, schema: {
type: :object,
properties: {
title: { type: :string },
author: { type: :string },
publisher: { type: :string },
editor: { type: :string }
}
}
response '200', 'book created' do
let(:book) { { title: 'New Book', author: 'New Author'}}
after do |example|
example.metadata[:response][:content] = {
'application/json' => {
example: JSON.parse(response.body, symbolize_names: true)
}
}
end
run_test! do |response|
data = JSON.parse(response.body)
expect(data['title']).to eq('New Book')
new_books_in_db = Book.where(title: 'New Book').count
expect(new_books_in_db).to eq(1)
end
end
end
end
end
The resulting swagger.json file is as follows
"openapi": "3.0.1",
"info": {
"title": "API V1",
"version": "v1"
},
"paths": {
"/api/v1/books": {
"get": {
"summary": "list books",
"parameters": [
{
"name": "Authorization",
"in": "header",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "successful"
}
}
}
},
"/api/v1/books/{id}": {
"parameters": [
{
"name": "id",
"in": "path",
"description": "id",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "Authorization",
"in": "header",
"schema": {
"type": "string"
}
}
],
"get": {
"summary": "show book",
"responses": {
"200": {
"description": "successful"
}
}
}
},
"api/v1/books": {
"post": {
"summary": "Creates a book",
"parameters": [
],
"responses": {
"200": {
"description": "book created"
}
},
"requestBody": {
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"title": {
"type": "string"
},
"author": {
"type": "string"
},
"publisher": {
"type": "string"
},
"editor": {
"type": "string"
}
}
}
}
}
}
}
}
},
"servers": [
{
"url": "https://{defaultHost}",
"variables": {
"defaultHost": {
"default": "www.example.com"
}
}
}
]
}
The complete code for the project is at https://github.com/marksack/rails_swagger_test (the master branch).
I have two questions/problems.
I have the code for auto generating the examples included as per the rswag documentation. But the auto generate is not working. What do I need to do to get the auto generation feature workin?
For our use case, we will get the most benefit if we can auto generate the schema for the request body. The rswag documentation does not indicate how to do that. How can I auto generate the schema for the request body?
UPDATE
For #1, I got it working by disabing dry run, i.e. the command needs to be SWAGGER_DRY_RUN=0 RAILS_ENV=test rails rswag
instead of RAILS_ENV=test rails rswag
.
For #2, I made a mistake in my question. I've updated the question above to reference the request body instead of the response body.