Generate API documentation using RSpec
rspec-api-docs provides a way to generate documentation from your request specs. It does this by providing a simple DSL and a custom formatter.
The default renderer produces a single JSON file which can be used by api-docs to display your documentation.
Add this line to your application's Gemfile:
gem 'rspec-api-docs'And then execute:
$ bundle
Or install it yourself as:
$ gem install rspec-api-docs
rspec-api-docs works in two stages. The first stage introduces a new DSL
method, doc, to include in your RSpec specs.
require 'rspec_api_docs/dsl'
RSpec.describe 'Characters' do
include RspecApiDocs::Dsl
# ...
endThe doc method stores data in a hash on the RSpec example metadata.
The second stage is the formatter (RspecApiDocs::Formatter). The formatter
parses the hash stored on each RSpec example and uses a
renderer to write out your
documentation.
$ rspec spec/requests/characters_spec.rb --formatter=RspecApiDocs::Formatter
First, require the DSL and include the DSL module.
You can do this in your spec_helper.rb:
require 'rspec_api_docs/dsl'
RSpec.configure do |config|
config.include RspecApiDocs::Dsl, type: :request
# ...
endOr in individual specs:
require 'rspec_api_docs/dsl'
RSpec.describe 'Characters' do
include RspecApiDocs::Dsl
# ...
endYou also need to require a lambda that runs after each expectation:
require 'rspec_api_docs/after'
RSpec.configure do |config|
config.after &RspecApiDocs::After::Hook
endThis automatically stores the last_request and last_response objects for
use by the formatter.
rspec-api-docs doesn't touch any of the built-in RSpec DSL methods.
Everything is contained in the doc block.
You can use RSpec before blocks to share setup between multiple examples.
require 'rspec_api_docs/dsl'
RSpec.describe 'Characters' do
include RspecApiDocs::Dsl
before do
doc do
resource_name 'Characters'
resource_description <<-EOF
Characters inhabit the Land of Ooo.
EOF
end
end
describe 'GET /characters/:id' do
it 'returns a character' do
doc do
name 'Fetching a Character'
description 'For getting information about a Character.'
path '/characters/:id'
field :id, 'The id of a character', scope: :character, type: 'integer'
field :name, "The character's name", scope: :character, type: 'string'
end
get '/characters/1'
# normal expectations ...
end
# ...
end
endAccepts a string of the name of the resource.
Characters
Accepts a string that describes the resource.
Characters inhabit the Land of Ooo.
Accepts an optional integer.
Lower numbers are ordered first.
Accepts a string of the name of the resource.
Fetching a character
Note: This defaults to the "description" of the RSpec example.
it 'Fetching a character' do
# ...
endAccepts a string that describes the example.
To find out information about a Character.
Accepts a string for the path requested in the example.
/characters/:id
Note: This defaults to the path of the first route requested in the example.
Accepts a name, description, and optionally a scope, type, and example.
name[Symbol] the name of the response fielddescription[String] a description of the response fieldscope[Symbol,Array<Symbol>] (optional) how the field is scopedtype[String] (optional) the type of the returned fieldexample(optional) an example value
This can be called multiple times for each response field.
field :id, 'The id of a character', scope: :character, type: 'integer', example: 42
field :name, "The character's name", scope: :character, type: 'string'The example is useful if the data might change (i.e. a database ID column).
The value will be substituted in the resulting JSON.
Accepts a name, description, and optionally a scope, type, and required flag.
name[Symbol] the name of the parameterdescription[Symbol] a description of the parameterscope[Symbol,Array<Symbol>] (optional) how the parameter is scopedtype[String] (optional) the type of the parameterrequired[Boolean] (optional) if the parameter is required
This can be called multiple times for each parameter.
param :id, 'The id of a character', scope: :character, type: 'integer', required: true
param :name, "The character's name", scope: :character, type: 'string'Accepts a note and optional level.
level[Symbol] one of:success,:info,:warning, or:danger. Defaults to:infonote[String] the note
note 'You need to supply an id!'
note :warning, "An error will be thrown if you don't supply an id!"Accepts an optional integer.
Lower numbers are ordered first.
See the integration specs for more examples of the DSL in use.
The formatter can be configured in your spec_helper.rb:
# Defaults are shown
RspecApiDocs.configure do |config|
# The output directory for file(s) created by the renderer.
config.output_dir = 'docs'
# One of :json, :raddocs, or :slate.
# This can also be a class that quacks like a renderer.
# A renderer is initialized with an array of `Resource`s and a `#render`
# method is called.
config.renderer = :json
# Set to false if you don't want to validate params are documented and their
# types in the after block.
config.validate_params = true
endSee the documentation.
require 'rspec_api_docs/rake_task'
RspecApiDocs::Rake.new do |task| # docs:generate
# Pattern for where to find the specs
task.pattern = 'spec/requests/**/*_spec.rb'
# Extra RSpec options
task.rspec_opts = ['--format progress']
end
RspecApiDocs::Rake.new do |task| # docs:ensure_updated
# Same as options above with some extras for when verify is true
# Raise an error if the generated docs don't match the existing docs
# The verify option only works with the :json renderer.
task.verify = true
# The existing (committed) output file
task.existing_file = 'docs/index.json'
end
# Non-verify task with custom name
RspecApiDocs::Rake.new :custom_task_nameAfter checking out the repo, run bin/setup to install dependencies. Then, run
rake to run the tests.
To install this gem onto your local machine, run bundle exec rake install. To
release a new version, update the version number in version.rb, and then run
bundle exec rake release, which will create a git tag for the version, push
git commits and tags, and push the .gem file to rubygems.org.
Regenerate this project's integration spec docs locally:
$ ./bin/generate_integration_docs
Bug reports and pull requests are welcome on GitHub at https://github.com/twe4ked/rspec-api-docs. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.
The gem is available as open source under the terms of the MIT License.