Skip to content

rswag/rswag

Repository files navigation

rswag

Build Status Maintainability

OpenApi 3.0 and Swagger 2.0 compatible!

Seeking maintainers! Got a pet-bug that needs fi xing? Just let us know in your issue/pr that you'd like to step up to help.

Rswag extends rspec-rails "request specs" with a Swagger-based DSL for describing and testing API operations. You describe your API operations with a succinct, intuitive syntax, and it automatically runs the tests. Once you have green tests, run a rake task to auto-generate corresponding Swagger files and expose them as YAML or JSON endpoints. Rswag also provides an embedded version of the awesomeswagger-uithat's powered by the exposed file. This toolchain makes it seamless to go from integration specs, which you're probably doing in some form already, to living documentation for your API consumers.

Api Rswag createsSwaggertooling for Rails API's. Generate beautiful API documentation, including a UI to explore and test operations, directly from your rspec integration tests.

And that's not all...

Once you have an API that can describe itself in Swagger, you've opened the treasure chest of Swagger-based tools including a client generator that can be targeted to a wide range of popular platforms. Seeswagger-codegenfor more details.

Table of Contents

Getting Started

  1. Add this line to your applicationsGemfile:

    gem'rswag'

    or if you like to avoid loading rspec in other bundler groups load the rswag-specs component separately. Note: Adding it to the:development group is not strictly necessary, but without it, generators and rake tasks must be preceded by RAILS_ENV=test.

    # Gemfile
    gem'rswag-api'
    gem'rswag-ui'
    
    group:development,:testdo
    gem'rspec-rails'
    gem'rswag-specs'
    end
  2. Run the install generator

    railsgrswag:install

    Or run the install generators for each package separately if you installed Rswag as separate gems, as indicated above:

    railsgrswag:api:install
    railsgrswag:ui:install
    RAILS_ENV=testrailsgrswag:specs:install
  3. Create an integration spec to describe and test your API. There is also a generator which can help get you startedrails generate rspec:swagger API::MyController

    # spec/requests/blogs_spec.rb
    require'swagger_helper'
    
    describe'Blogs API'do
    
    path'/blogs'do
    
    post'Creates a blog'do
    tags'Blogs'
    consumes'application/json'
    parametername::blog,in::body,schema:{
    type::object,
    properties:{
    title:{type::string},
    content:{type::string}
    },
    required:['title','content']
    }
    
    response'201','blog created'do
    let(:blog){{title:'foo',content:'bar'}}
    run_test!
    end
    
    response'422','invalid request'do
    let(:blog){{title:'foo'}}
    run_test!
    end
    end
    end
    
    path'/blogs/{id}'do
    
    get'Retrieves a blog'do
    tags'Blogs','Another Tag'
    produces'application/json','application/xml'
    parametername::id,in::path,type::string
    request_body_examplevalue:{some_field:'Foo'},name:'basic',summary:'Request example description'
    
    response'200','blog found'do
    schematype::object,
    properties:{
    id:{type::integer},
    title:{type::string},
    content:{type::string}
    },
    required:['id','title','content']
    
    let(:id){Blog.create(title:'foo',content:'bar').id}
    run_test!
    end
    
    response'404','blog not found'do
    let(:id){'invalid'}
    run_test!
    end
    
    response'406','unsupported accept header'do
    let(:'Accept'){'application/foo'}
    run_test!
    end
    end
    end
    end

By default, the above command will create spec underspec/requestsfolder. You can pass an option to change this default path as inrails generate rspec:swagger API::BlogsController --spec_path integration. This will create the spec filespec/integration/blogs_spec.rb

  1. Generate the Swagger JSON file(s)

    rakerswag:specs:swaggerize

    This common command is also aliased asrake rswag.

    Or if you installed your gems separately:

    RAILS_ENV=test rails rswag
    
  2. Spin up your app and check out the awesome, auto-generated docs at/api-docs!

The rspec DSL

Paths, Operations and Responses

If you've usedSwaggerbefore, then the syntax should be very familiar. To describe your API operations, start by specifying a path and then list the supported operations (i.e. HTTP verbs) for that path. Path parameters must be surrounded by curly braces ({}). Within an operation block (see "post" or "get" in the example above), most of the fields supported by theSwagger "Operation" objectare available as methods on the example group. To list (and test) the various responses for an operation, create one or more response blocks. Again, you can reference theSwagger "Response" objectfor available fields.

Take special note of therun_test!method that's called within each response block. This tells rswag to create and execute a corresponding example. It builds and submits a request based on parameter descriptions and corresponding values that have been provided using the rspec "let" syntax. For example, the "post" description in the example above specifies a "body" parameter called "blog". It also lists 2 different responses. For the success case (i.e. the 201 response), notice how "let" is used to set the blog parameter to a value that matches the provided schema. For the failure case (i.e. the 422 response), notice how it's set to a value that does not match the provided schema. When the test is executed, rswag also validates the actual response code and, where applicable, the response body against the providedJSON Schema.

If you want to add metadata to the example, you can pass keyword arguments to therun_test!method:

# to run particular test case
response'201','blog created'do
run_test!focus:true
end

# to write vcr cassette
response'201','blog created'do
run_test!vcr:true
end

If you want to customize the description of the generated specification, a description can be passed torun_test!

response'201','blog created'do
run_test!"custom spec description"
end

If you want to do additional validation on the response, pass a block to therun_test!method:

response'201','blog created'do
run_test!do|response|
data=JSON.parse(response.body)
expect(data['title']).toeq('foo')
end
end

If you'd like your specs to be a little more explicit about what's going on here, you can replace the call torun_test!with equivalent "before" and "it" blocks:

response'201','blog created'do
let(:blog){{title:'foo',content:'bar'}}

beforedo|example|
submit_request(example.metadata)
end

it'returns a valid 201 response'do|example|
assert_response_matches_metadata(example.metadata)
end
end

Also note that the examples generated withrun_test!are tagged with the:rswagso they can easily be filtered. E.g.rspec --tag rswag

date-time in query parameters

Input sent in queries of Rspec tests is HTML safe, including date-time strings.

parametername::date_time,in::query,type::string

response'200','blog found'do
let(:date_time){DateTime.new(2001,2,3,4,5,6,'-7').to_s}

run_test!do
expect(request[:path]).toeq('/blogs?date_time=2001-02-03T04%3A05%3A06-07%3A00')
end
end

Enum description

If you want to output a description of each enum value, the description can be passed to each value:

parametername::status,in::query,getter::blog_status,
enum:{'draft':'Retrieves draft blogs','published':'Retrieves published blogs','archived':'Retrieves archived blogs'},
description:'Filter by status'

response'200','success'do
let(:blog_status){'published'}

run_test!
end

Strict schema validation

By default, if response body contains undocumented properties tests will pass. To keep your responses clean and validate against a strict schema definition you can set the global config option:

# spec/swagger_helper.rb
RSpec.configuredo|config|
config.openapi_strict_schema_validation=true
end

or set the option per individual example:

# using in run_test!
describe'Blogs API'do
path'/blogs'do
post'Creates a blog'do
...
response'201','blog created'do
let(:blog){{title:'foo',content:'bar'}}

run_test!(openapi_strict_schema_validation:true)
end
end
end
end

# using in response block
describe'Blogs API'do
path'/blogs'do
post'Creates a blog'do
...

response'201','blog created',openapi_strict_schema_validation:truedo
let(:blog){{title:'foo',content:'bar'}}

run_test!
end
end
end
end

# using in an explicit example
describe'Blogs API'do
path'/blogs'do
post'Creates a blog'do
...
response'201','blog created'do
let(:blog){{title:'foo',content:'bar'}}

beforedo|example|
submit_request(example.metadata)
end

it'returns a valid 201 response',openapi_strict_schema_validation:truedo|example|
assert_response_matches_metadata(example.metadata)
end
end
end
end
end

Null Values

This library is currently using JSON::Draft4 for validation of response models. Nullable properties can be supported with the non-standard property 'x-nullable' to a definition to allow null/nil values to pass. Or you can add the new standardnullableproperty to a definition.

describe'Blogs API'do
path'/blogs'do
post'Creates a blog'do
...

response'200','blog found'do
schematype::object,
properties:{
id:{type::integer},
title:{type::string,nullable:true},# preferred syntax
content:{type::string,'x-nullable':true}# legacy syntax, but still works
}
....
end
end
end
end

Support for oneOf, anyOf or AllOf schemas

Open API 3.0 now supports more flexible schema validation with theoneOf,anyOfandallOfdirectives. rswag will handle these definitions and validate them properly.

Notice theschemainside theresponsesection. Placing aschemamethod 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:

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'

parametername::blog,in::body,schema:{
oneOf:[
{'$ref'=>'#/components/schemas/blog'},
{'$ref'=>'#/components/schemas/flexible_blog'}
]
}

response'201','flexible blog created'do
schemaoneOf:[{'$ref'=>'#/components/schemas/blog'},{'$ref'=>'#/components/schemas/flexible_blog'}]
run_test!
end
end
end

This automatic schema validation is a powerful feature of rswag.

Global Metadata

In addition to paths, operations and responses, Swagger also supports global API metadata. When you install rswag, a file calledswagger_helper.rbis added to your spec folder. This is where you define one or more Swagger documents and provide global metadata. Again, the format is based on Swagger so most of the global fields supported by the top level"Swagger" objectcan be provided with each document definition. As an example, you could define a Swagger document for each version of your API and in each case specify a title, version string. In Open API 3.0 the pathing and server definitions have changed a bitSwagger host/basePath:

# spec/swagger_helper.rb
RSpec.configuredo|config|
config.openapi_root=Rails.root.to_s+'/swagger'

config.openapi_specs={
'v1/swagger.json'=>{
openapi:'3.0.1',
info:{
title:'API V1',
version:'v1',
description:'This is the first version of my API'
},
servers:[
{
url:'https://{defaultHost}',
variables:{
defaultHost:{
default:' example '
}
}
}
]
},

'v2/swagger.json'=>{
openapi:'3.0.1',
info:{
title:'API V2',
version:'v2',
description:'This is the second version of my API'
},
servers:[
{
url:'{protocol}://{defaultHost}',
variables:{
protocol:{
default::https
},
defaultHost:{
default:' example '
}
}
}
]
}
}
end

Supporting multiple versions of API

By default, the paths, operations and responses defined in your spec files will be associated with the first Swagger document inswagger_helper.rb.If your API has multiple versions, you should be using separate documents to describe each of them. In order to assign a file with a given version of API, you'll need to add theopenapi_spectag to each spec specifying its target document name:

# spec/requests/v2/blogs_spec.rb
describe'Blogs API',openapi_spec:'v2/swagger.yaml'do

path'/blogs'do
...

path'/blogs/{id}'do
...
end

Supporting YAML format

By default, the swagger docs are generated in JSON format. If you want to generate them in YAML format, you can specify the swagger format in the swagger_helper.rb file:

# spec/swagger_helper.rb
RSpec.configuredo|config|
config.openapi_root=Rails.root.to_s+'/swagger'

# Use if you want to see which test is running
# config.formatter =:documentation

# Generate swagger docs in YAML format
config.openapi_format=:yaml

config.openapi_specs={
'v1/swagger.yaml'=>{
openapi:'3.0.1',
info:{
title:'API V1',
version:'v1',
description:'This is the first version of my API'
},
servers:[
{
url:'https://{defaultHost}',
variables:{
defaultHost:{
default:' example '
}
}
}
]
},
}
end

Formatting the description literals:

Swagger supports the Markdown syntax to format strings. This can be especially handy if you were to provide a long description of a given API version or endpoint. Usethis guidefor reference.

NOTE:There is one difference between the official Markdown syntax and Swagger interpretation, namely tables. To create a table like this:

Column1 Column2
cell1 cell2

you should use the following syntax, making sure there is no whitespace at the start of any of the lines:


| Column1 | Column2 | 
 |
| ------- | ------- |
| cell1 | cell2 |


Specifying/Testing API Security

Swagger allows for the specification of different security schemes and their applicability to operations in an API. To leverage this in rswag, you define the schemes globally inswagger_helper.rband then use the "security" attribute at the operation level to specify which schemes, if any, are applicable to that operation. Swagger supports:basic,:bearer,:apiKey and:oauth2 and:openIdConnect scheme types. Seethe specfor more info, as this underwent major changes between Swagger 2.0 and Open API 3.0

# spec/swagger_helper.rb
RSpec.configuredo|config|
config.openapi_root=Rails.root.to_s+'/swagger'

config.openapi_specs={
'v1/swagger.json'=>{
...# note the new Open API 3.0 compliant security structure here, under "components"
components:{
securitySchemes:{
basic_auth:{
type::http,
scheme::basic
},
api_key:{
type::apiKey,
name:'api_key',
in::query
}
}
}
}
}
end

# spec/requests/blogs_spec.rb
describe'Blogs API'do

path'/blogs'do

post'Creates a blog'do
tags'Blogs'
security[basic_auth:[]]
...

response'201','blog created'do
let(:Authorization){"Basic#{::Base64.strict_encode64('jsmith:jspass')}"}
run_test!
end

response'401','authentication failed'do
let(:Authorization){"Basic#{::Base64.strict_encode64('bogus:bogus')}"}
run_test!
end
end
end
end

# example of documenting an endpoint that handles basic auth and api key based security
describe'Auth examples API'do
path'/auth-tests/basic-and-api-key'do
post'Authenticates with basic auth and api key'do
tags'Auth Tests'
operationId'testBasicAndApiKey'
security[{basic_auth:[],api_key:[]}]

response'204','Valid credentials'do
let(:Authorization){"Basic#{::Base64.strict_encode64('jsmith:jspass')}"}
let(:api_key){'foobar'}
run_test!
end

response'401','Invalid credentials'do
let(:Authorization){"Basic#{::Base64.strict_encode64('jsmith:jspass')}"}
let(:api_key){'bar-foo'}
run_test!
end
end
end
end

NOTE:Depending on the scheme types, you'll be required to assign a corresponding parameter value with each example. For example,:basic auth is required above and so the:Authorization (header) parameter must be set accordingly

Configuration & Customization

The steps described above will get you up and running with minimal setup. However, rswag offers a lot of flexibility to customize as you see fit. Before exploring the various options, you'll need to be aware of its different components. The following table lists each of them and the files that get added/updated as part of a standard install.

Gem Description Added/Updated
rswag-specs Swagger-based DSL for rspec & accompanying rake task for generating Swagger files spec/swagger_helper.rb
rswag-api Rails Engine that exposes your Swagger files as JSON endpoints config/initializers/rswag_api.rb, config/routes.rb
rswag-ui Rails Engine that includesswagger-uiand powers it from your Swagger endpoints config/initializers/rswag-ui.rb, config/routes.rb

Output Location for Generated Swagger Files

You can adjust this in theswagger_helper.rbthat's installed withrswag-specs:

# spec/swagger_helper.rb
RSpec.configuredo|config|
config.openapi_root=Rails.root.to_s+'/your-custom-folder-name'
...
end

NOTE:If you do change this, you'll also need to update the rswag_api.rb initializer (assuming you're using rswag-api). More on this later.

Input Location for Rspec Tests

By default, rswag will search for integration tests inspec/requests,spec/apiandspec/integration.If you want to use tests from other locations, provide the PATTERN argument to rake:

# search for tests in spec/swagger
rakerswag:specs:swaggerizePATTERN="spec/swagger/**/*_spec.rb"

Additional rspec options

You can add additional rspec parameters using the ADDITIONAL_RSPEC_OPTS env variable:

# Only include tests tagged "rswag"
rakerswag:specs:swaggerizeADDITIONAL_RSPEC_OPTS="--tag rswag"

Referenced Parameters and Schema Definitions

Swagger allows you to describe JSON structures inline with your operation descriptions OR as referenced globals. For example, you might have a standard response structure for all failed operations. Again, this is a structure that changed since swagger 2.0. Notice the new "schemas" section for these. Rather than repeating the schema in every operation spec, you can define it globally and provide a reference to it in each spec:

# spec/swagger_helper.rb
config.openapi_specs={
'v1/swagger.json'=>{
openapi:'3.0.0',
info:{
title:'API V1'
},
components:{
schemas:{
errors_object:{
type:'object',
properties:{
errors:{'$ref'=>'#/components/schemas/errors_map'}
}
},
errors_map:{
type:'object',
additionalProperties:{
type:'array',
items:{type:'string'}
}
},
blog:{
type:'object',
properties:{
id:{type:'integer'},
title:{type:'string'},
content:{type:'string',nullable:true},
thumbnail:{type:'string',nullable:true}
},
required:%w[idtitle]
},
new_blog:{
type:'object',
properties:{
title:{type:'string'},
content:{type:'string',nullable:true},
thumbnail:{type:'string',format:'binary',nullable:true}
},
required:%w[title]
}
}
}
}
}

# spec/requests/blogs_spec.rb
describe'Blogs API'do

path'/blogs'do

post'Creates a blog'do

parametername::new_blog,in::body,schema:{'$ref'=>'#/components/schemas/new_blog'}

response422,'invalid request'do
schema'$ref'=>'#/components/schemas/errors_object'
...
end

# spec/requests/comments_spec.rb
describe'Blogs API'do

path'/blogs/{blog_id}/comments'do

post'Creates a comment'do

response422,'invalid request'do
schema'$ref'=>'#/components/schemas/errors_object'
...
end

Request examples

# spec/integration/blogs_spec.rb
describe'Blogs API'do

path'/blogs/{blog_id}'do

get'Retrieves a blog'do

request_body_examplevalue:{some_field:'Foo'},name:'request_example_1',summary:'A request example'

response200,'blog found'do
...

to use the actual request from the spec as the example:

config.after(:each,operation:true,use_as_request_example:true)do|spec|
spec.metadata[:operation][:request_examples]||=[]

example={
value:JSON.parse(request.body.string,symbolize_names:true),
name:'request_example_1',
summary:'A request example'
}

spec.metadata[:operation][:request_examples]<<example
end

Response headers

In Rswag, you could useheadermethod inside the response block to specify header objects for this response. Rswag will validate your response headers with those header objects and inject them into the generated swagger file:

# spec/requests/comments_spec.rb
describe'Blogs API'do

path'/blogs/{blog_id}/comments'do

post'Creates a comment'do

response422,'invalid request'do
header'X-Rate-Limit-Limit',schema:{type::integer},description:'The number of allowed requests in the current period'
header'X-Rate-Limit-Remaining',schema:{type::integer},description:'The number of remaining requests in the current period'
...
end

Nullable or Optional Response Headers

You can includenullableorrequiredto specify whether a response header must be present or may be null. Whennullableis not included, the headers validation validates that the header response is non-null. Whenrequiredis not included, the headers validation validates the the header response is passed.

# spec/integration/comments_spec.rb
describe'Blogs API'do

path'/blogs/{blog_id}/comments'do

get'Gets a list of comments'do

response200,'blog found'do
header'X-Cursor',schema:{type::string,nullable:true},description:'The cursor to get the next page of comments.'
header'X-Per-Page',schema:{type::integer},required:false,description:'The number of comments per page.'
...
end

Response examples

You can provide custom response examples to the generated swagger file by calling the methodexamplesinside the response block: However, auto generated example responses are now enabled by default in rswag. See below.

# spec/requests/blogs_spec.rb
describe'Blogs API'do

path'/blogs/{blog_id}'do

get'Retrieves a blog'do

response200,'blog found'do
example'application/json',:example_key,{
id:1,
title:'Hello world!',
content:'...'
}
example'application/json',:example_key_2,{
id:1,
title:'Hello world!',
content:'...'
},"Summary of the example","Longer description of the example"
...
end

Enable auto generation examples from responses

To enable examples generation from responses add callback above run_test! like:

afterdo|example|
content=example.metadata[:response][:content]||{}
example_spec={
"application/json"=>{
examples:{
test_example:{
value:JSON.parse(response.body,symbolize_names:true)
}
}
}
}
example.metadata[:response][:content]=content.deep_merge(example_spec)
end

Dry Run Option

The--dry-runoption is enabled by default for Rspec 3, but if you need to disable it you can use the environment variableRSWAG_DRY_RUN=0during the generation command or add the following to yourconfig/environments/test.rb:

RSpec.configuredo|config|
config.rswag_dry_run=false
end

Running tests without documenting

If you want to use Rswag for testing without adding it to you swagger docs, you can provide the document tag:

describe'Blogs API'do
path'/blogs/{blog_id}'do
get'Retrieves a blog'do
# documentation is now disabled for this response only
response200,'blog found',document:falsedo
...

You can also reenable documentation for specific responses only:

# documentation is now disabled
describe'Blogs API',document:falsedo
path'/blogs/{blog_id}'do
get'Retrieves a blog'do
# documentation is reenabled for this response only
response200,'blog found',document:truedo
...
end

response401,'special case'do
...
end
rswag helper methods

Route Prefix for Swagger JSON Endpoints

The functionality to expose Swagger files, such as those generated by rswag-specs, as JSON endpoints is implemented as a Rails Engine. As with any Engine, you can change its mount prefix inroutes.rb:

TestApp::Application.routes.drawdo
...

mountRswag::Api::Engine=>'your-custom-prefix'
end

Assuming a Swagger file exists at <openapi_root>/v1/swagger.json, this configuration would expose the file as the following JSON endpoint:

GET http://<hostname>/your-custom-prefix/v1/swagger.json

Root Location for Swagger Files

You can adjust this in therswag_api.rbinitializer that's installed withrspec-api:

Rswag::Api.configuredo|c|
c.openapi_root=Rails.root.to_s+'/your-custom-folder-name'
...
end

NOTE:If you're using rswag-specs to generate Swagger files, you'll want to ensure they both use the same <openapi_root>. The reason for separate settings is to maintain independence between the two gems. For example, you could install rswag-api independently and create your Swagger files manually.

Dynamic Values for Swagger JSON

There may be cases where you need to add dynamic values to the Swagger JSON that's returned by rswag-api. For example, you may want to provide an explicit host name. Rather than hardcoding it, you can configure a filter that's executed prior to serializing every Swagger document:

Rswag::Api.configuredo|c|
...

c.swagger_filter=lambda{|swagger,env|swagger['host']=env['HTTP_HOST']}
end

Note how the filter is passed the rack env for the current request. This provides a lot of flexibility. For example, you can assign the "host" property (as shown) or you could inspect session information or an Authorization header and remove operations based on user permissions.

Custom Headers for Swagger Files

You can specify custom headers for serving your generated Swagger JSON. For example you may want to force a specific charset for the 'Content-Type' header. You can configure a hash of headers to be sent with the request:

Rswag::Api.configuredo|c|
...

c.swagger_headers={'Content-Type'=>'application/json; charset=UTF-8'}
end

Take care when overriding Content-Type if you serve both YAML and JSON files as it will no longer switch the Content-Type header correctly.

Enable Swagger Endpoints for swagger-ui

You can update therswag_ui.rbinitializer, installed with rswag-ui, to specify which Swagger endpoints should be available to power the documentation UI. If you're using rswag-api, these should correspond to the Swagger endpoints it exposes. When the UI is rendered, you'll see these listed in a drop-down to the top right of the page:

Rswag::Ui.configuredo|c|
c.openapi_endpoint'/api-docs/v1/swagger.json','API V1 Docs'
c.openapi_endpoint'/api-docs/v2/swagger.json','API V2 Docs'
end

Enable Simple Basic Auth for swagger-ui

You can also update therswag_ui.rbinitializer, installed with rswag-ui to specify a username and password should you want to keep your documentation private.

Rswag::Ui.configuredo|c|
c.basic_auth_enabled=true
c.basic_auth_credentials'username','password'
end

Route Prefix for the swagger-ui

Similar to rswag-api, you can customize the swagger-ui path by changing its mount prefix inroutes.rb:

TestApp::Application.routes.drawdo
...

mountRswag::Api::Engine=>'api-docs'
mountRswag::Ui::Engine=>'your-custom-prefix'
end

Customizing the swagger-ui

The swagger-ui provides several options for customizing its behavior, all of which are documented herehttps://github /swagger-api/swagger-ui/tree/2.x#swaggerui.If you need to tweak these or customize the overall look and feel of your swagger-ui, then you'll need to provide your own version of index.html. You can do this with the following generator.

railsgrswag:ui:custom

This will add a local version that you can modify atapp/views/rswag/ui/home/index.html.erb.For example, it will let you to add your own<title>and favicon.

To replace the"Swagger sponsored by"brand image, you can add the following script to the generated file:

<script>
(function(){
window.addEventListener("load",function(){
setTimeout(function(){

varlogo=document.getElementsByClassName('link');

logo[0].children[0].alt="My API";
logo[0].children[0].src="/favicon.png";
});
});})();
</script>

The above script would expect to find an image namedfavicon.pngin the public folder.

Serve UI Assets Directly from your Web Server

Rswag ships with an embedded version of theswagger-ui,which is a static collection of JavaScript and CSS files. These assets are served by the rswag-ui middleware. However, for optimal performance you may want to serve them directly from your web server (e.g. Apache or NGINX). To do this, you'll need to copy them to the web server root. This is the "public" folder in a typical Rails application.

bundle exec rake rswag:ui:copy_assets[public/api-docs]

NOTE::The provided subfolder MUST correspond to the UI mount prefix - "api-docs" by default.

Notes to test swagger output locally with swagger editor

docker pull swaggerapi/swagger-editor
docker run -d -p 80:8080 swaggerapi/swagger-editor

This will run the swagger editor in the docker daemon and can be accessed athttp://localhost.From here, you can use the UI to load the generated swagger.json to validate the output.

Custom:getter option for parameter

To avoid conflicts with Rspecincludematcher and other possible intersections likestatusmethod:

...
parameter name::status,
getter::filter_status,
in::query,
schema: {
type::string,
enum: %w[one two three],
}, required: false

let(:status) { nil } # will not be used in query string
let(:filter_status) { 'one' } # `&status=one` will be provided in final query

Linting with RuboCop RSpec

When you lint your RSpec spec files withrubocop-rspec,it will fail to detect RSpec aliases that Rswag defines. Make sure to userubocop-rspec2.0 or newer and add the following to your.rubocop.yml:

inherit_gem:
rswag-specs:.rubocop_rspec_alias_config.yml