bjk3pa
Last Updated: August 10, 2016
·
17.96K
· cybersamx
Portrait sam

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.

4 Responses
Add your response

18145
9078270e9f444d6e6c67e5f16df47efc

Samuel Chow, Thank you for this!

One question, how did you manage authorization through Headers for your API docs?

over 1 year ago ·
18961
None

This was very helpful. Thanks!

over 1 year ago ·
21239
Da06eb3e2b022a45aeb0944a09a2134b

Nice! Do you know if there's a way to automatically test the API, or do you maintain a separate suite of automated-tests?

over 1 year ago ·
28048
27ca9066ad05bd8aa9ec366115f3cd38

The git address has changed:
git submodule add https://github.com/swagger-api/swagger-ui.git swagger

7 months ago ·