Last Updated: July 26, 2022
·
55.82K
· cybersamx

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.

5 Responses
Add your response

Samuel Chow, Thank you for this!

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

over 1 year ago ·

This was very helpful. Thanks!

over 1 year ago ·

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 ·

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

over 1 year ago ·

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

over 1 year ago ·