Documenting Rails-based REST API using Swagger UI
Problem
You built a REST API server using Rails and you need to document and test the endpoints.
The Setup
Let's assume the following:
- REST endpoint: /api/v1/posts
- Rails controller: app/controllers/api/v1/posts_controller.rb
Steps
1 - Add the following to the Gemfile and run bundle afterwards.
# Swagger
gem 'swagger-docs'
$ bundle
2 - Say you decide to structure your REST path in the following format: /api/v1/{method}. Edit app/controllers/api/v1/posts_controller.rb and add the following:
# app/controllers/api/v1/posts_controller.rb
module Api
module V1
class PostsController < ApplicationController
respond_to :json
swagger_controller :posts, 'Posts'
swagger_api :index do
summary 'Returns all posts'
notes 'Notes...'
end
def index
@posts = Post.all
render json: @posts, status: :ok
end
end
end
end
The swagger_api</code> block represents the documentation for posts#index. When we run the command "rake swagger:docs" later, the info will be used to generate the posts.json file that Swagger UI uses to render the REST documentation.
3 - Generate config/initializers/swagger.rb
# config/initializers/swagger.rb
class Swagger::Docs::Config
def self.transform_path(path, api_version)
# Make a distinction between the APIs and API documentation paths.
"apidocs/#{path}"
end
end
Swagger::Docs::Config.register_apis({
'1.0' => {
controller_base_path: '',
api_file_path: 'public/apidocs',
base_path: 'http://localhost:3000',
clean_directory: true
}
})
When we run the command "rake swagger:docs" later, the info entered here will generate the api-docs.json file that is read by Swagger UI to generate the HTML page to display the documentation of the API.
Note that we override the transformpath method in Swagger::Docs::Config to place the documentation files (which are located in api-docs.json and a *.json for each of the controllers) in a directory that is different from the actual API endpoints. This prevents any possible conflicts of URL since the path of documentation file generated from "rake swagger:docs" likely conflicts with the #index route. For example, if we don't override #transformpath both the documentation path for PostsController and the hosted API endpoint for posts#index will share the same URI path (/api/v1/posts.json), leading to a conflict.
4 - Also it a good practice not to check the generated Swagger documentation files into git. So we include the generated json files in .gitigore. Because all the generated files are saved under public/apidocs, it becomes easy to include those files in .gitignore.
## Ignore Swagger JSON files.
/public/apidocs/
5 - Generate the API docs. You must run the following command to generate new documentation json files everytime you change the API endpoints.
$ rake swagger:docs
The API documentation will be generated in the public/apidocs directory.
Read this doc for more info on Swagger Docs.
6 - So far, we have configure our project to generate Swagger documentation files. We now need Swagger UI installed in our project. This isn't the final solution, but we can clone Swagger UI by creating a submodule in the public directory. This way Swagger UI can be served via the rails server.
$ cd public
$ git submodule add git@github.com:wordnik/swagger-ui.git swagger
Read this doc for more info on Swagger UI.
7 - As a convenience, we can add the following redirection in the routes.rb. This way, path /api will redirect us to the Swagger UI home page located in public/swagger/dist/index.html.
By default, the Swagger UI home page retrieves the api-docs.json documentation file from http://petstore.swagger.wordnik.com/. We can override this behavior by appending a URI parameter url to the URL ie. /swagger/dist/index.html?url=/apidocs/api-docs.json.
# config/routes.rb
get '/api' => redirect('/swagger/dist/index.html?url=/apidocs/api-docs.json')
8 - Run the Rails server.
$ rails s
9 - Launch a web browser and go to http://localhost:3000/api.
Written by Samuel Chow
Related protips
5 Responses
Samuel Chow, Thank you for this!
One question, how did you manage authorization through Headers for your API docs?
This was very helpful. Thanks!
Nice! Do you know if there's a way to automatically test the API, or do you maintain a separate suite of automated-tests?
The git address has changed:
git submodule add https://github.com/swagger-api/swagger-ui.git swagger
Thank you for sharing, Samuel! Unfortunately, swagger-docs supports Swagger 1.2 version only, - what is really outdated compared to the latest OpenAPI 3 version. See https://github.com/richhollis/swagger-docs#swagger-version-specification-support