Swagger Docs

Swagger Docs, is a gem which includes the Swagger::Docs gem and the assets for the SwaggerUI.

Goal of Swagger Docs

To easily setup API documentation with Swagger and the SwaggerUI.

Installation

Add this line to your application's Gemfile:

# Use this to fetch the gem from Gitlab
gem 'swagger_docs', git: '[email protected]:jvanderpas/swagger_docs.git'

# Use this to fetch the gem from RubyGems.org
gem 'ddy_swagger_docs', require: 'swagger_docs'

Configuration

  1. Add the stylesheet and javascript manifests to your assets (or used the advanced configuration):

    // app/assets/javascripts/application.js
    //= require swagger_docs
    //= require_tree .
    
    # app/assets/stylesheets/application.css
    *= require swagger_docs
    *= require_tree .
    *= require_self
    
  2. Add the Swagger::Docs configuration to your initializers:

    # config/initializers/swagger_docs.rb
    class Swagger::Docs::Config
      def self.transform_path(path, api_version)
        # Make a distinction between the APIs and API documentation paths.
        "api/#{path}"
      end
    end
    
    Swagger::Docs::Config.register_apis(
        {
            '1.0' => {
                api_extension_type: :json,
                controller_base_path: '',
                api_file_path: 'public/api',
                base_path: 'http://localhost:3000',
                clean_directory: true,
                camelize_model_properties: false,
                attributes: {
                    info: {
                        title: 'Dummy API',
                        description: 'JSON-based API accessible only for authorized users. Resource objects can be retrieved and written via this API. Keep in mind that any tries you do via this API will be done via the currently logged in profile.'
                    }
                }
            }
        }
    )
    
  3. Create a page in which you want to display the SwaggerUI, and add:

    <div class="swagger-section">
        <div class="swagger-ui-wrap" id="message-bar"></div>
        <div class="swagger-ui-wrap" id="swagger-ui-container"></div>
    </div>
    
  4. Visit the page and verify that the SwaggerUI is displayed.

Usage

Write the API documentation with the Swagger::Docs DSL in your controllers:

module Api
  class PostsController < BaseController

    swagger_controller :users, 'Posts'

    swagger_model :Post do
      description 'Post'
      property :id, :string, :required, '#id', example: '1430311887'
      property :title, :string, :required, '#title', example: 'My morning breakfast'
      property :body, :text, :optional, '#body', example: 'Every morning I make myself a cup of coffee, some orange juice and a bowl of muesli.'
    end

    swagger_api :index do
      summary 'Lists Posts'
      response :ok, nil
    end

    def index
      @posts = Post.all

      render json: @posts
    end

    swagger_api :show do
      summary 'Find a Post'
      param :path, :id, :string, :required, 'Post#id'
      response :ok, nil, :Post
      response :not_found
    end

    def show
      @post = Post.find(params[:id])

      render json: @post
    end

    swagger_api :create do
      summary 'Create a Post'
      param :body, :post, :post_params, :required
      response :created, nil, :Post
      response :unprocessable_entity, 'Unprocessable entity. Contains a JSON array of error messages.'
    end

    def create
      @post = Post.create(post_params)

      if @post.persisted?
        render json: @post, status: :created
      else
        render json: { errors: @post.errors.messages }, status: :unprocessable_entity
      end
    end

    swagger_api :update do
      summary 'Update a Post'
      param :path, :id, :string, :required, 'Post#id'
      param :body, :post, :post_params, :required
      response :accepted, nil, :Post
      response :unprocessable_entity, 'Unprocessable entity. Contains a JSON array of error messages.'
      response :not_found
    end

    def update
      @post = Post.find(params[:id])

      if @post.update_attributes(post_params)
        render json: @post, status: :accepted
      else
        render json: { errors: @post.errors.messages }, status: :unprocessable_entity
      end
    end

    swagger_api :destroy do
      summary 'Delete a Post'
      param :path, :id, :string, :required, 'Post#id'
      response :no_content, 'No content. Successful deleted the resource.'
      response :unprocessable_entity, 'Unprocessable entity. Contains a JSON array of error messages.'
      response :not_found
    end

    def destroy
      @post = Post.find(params[:id])

      if @post.destroy
        head :no_content
      else
        render json: { errors: @post.errors.messages }, status: :unprocessable_entity
      end
    end

    private

    swagger_model :post_params do
      description 'Post params'
      property :title, :string, :required, '#title', example: 'My lunch'
      property :body, :string, :optional, '#body', example: 'During the lunch I make myself two sandwiches with peanut butter and jam.'
    end

    def post_params
      params.require(:post).permit(:title, :body)
    end

  end
end

Generate the Swagger API documentation using a Rake task:

$ rake swagger:docs

Advanced configuration

When your application has an Admin or Devops interface, you might want to restrict serving the Swagger Docs assets. You can do this by using separate stylesheet and javascript manifests for the Admin or Devops interface. See the example below:

// app/assets/javascripts/devops/application.js
//= require swagger_docs
//= require_tree .
// app/assets/javascripts/application.js
//= stub ./devops/application
//= require_tree .
# app/assets/stylesheets/devsops/application.css
*= require swagger_docs
*= require_tree .
*= require_self
# app/assets/stylesheets/application.css
*= stub ./devops/application
*= require_tree .
*= require_self
# app/views/layouts/devops.html.erb
<%= stylesheet_link_tag    'devops/application', media: 'all' %>
<%= stylesheet_link_tag    'application', media: 'all' %>
<%= javascript_include_tag 'devops/application' %>
<%= javascript_include_tag 'application' %>