Gem Version

OpenAPI

CRUD interface for Rails models with OpenAPI (Swagger) specification support and Swagger UI integration.

This gem supports only Mongoid, for other ORMs RPs are welcome.

Demo project for basic openapi-rails integration.

Installation

Add to your Gemfile:

gem 'openapi-rails'

For new projects we recommend to run generator to create basic setup:

rake g openapi:config

If you have an existing project, please look through this readme file first to get an idea of how it works.

Generator is creating configuration file config/initializer/openapi.rb with default /api configuration and base controller app/controllers/api/base_controlle.rb that provides CRUD actions and specification builder.

Usage

Here projects API considered to be available at /api. Please check out Multiple APIs section for other options.

To add CRUD interface for the Project model create an empty controller that inherits from BaseController at app/controllers/api/projects_controller.rb:

module Api
  class ProjectsController < BaseController
  end
end

Map controller with crud helper, mount specification and documentation in routes.rb:

Rails.application.routes.draw do
  namespace :api do
    crud :projects
    # Mount OpenAPI specification for API
    mount_openapi_specification name: :default
  end

  # Mount Swagger UI documentation for API
  mount_openapi_documentation
end

Add Api::ProjectsController to config/initializer/openapi.rb controllers arrays of the default configuration:

Openapi.configure do |config|
  config.apis = {
    default: {
      title: 'Default',
      description: '',
      version: '1.0',
      base_path: '/api',
      controllers: [Api::ProjectsController]
    }
  }
end

Restart develoment server and open http://localhost:3000/openapi where API documentation is served.

OpenAPI Rails Demo

Meta information about mapped actions and model fields is pulled automatically on project initialization. Changes in routes.rb or models would require server restart to be reflected in documentation.

In documentation interface for create and update actions request Example Value includes only required fields. Other model fields should be added manually.

Supported Features

Following features are supported out of the box:

Customization

In the controller there is a way override default behaviour with helpers:

  • paginates_per(number) — set page size (default 50) for index action
  • resource_class(klass) — set model class manually
  • def resource_params — override default method that allows everything

Helpers to customize specification build:

  • spec_params(options)

Supported specification options:

  • collection_name
  • resource_name
  • resource_class
  • except_actions
  • relative_path

Custom Actions

Mapped custom actions (not CRUD) will add a log message on server start that controller misses specification. As a result they are not added to documentation.

Specification for custom methods should be added manually. Check out Swagger Blocks gem or specification builder code for DSL reference.

Here is an example of custom method specification:

module Api
  class ProjectsController < BaseController
    def custom_resource_action
      # TODO: Method implemetation goes here.
    end

    swagger_path "/projects/{id}/custom_resource_action" do
      operation :get do
        key :tags,        ["Projects"]
        key :summary,     'Show extra details'
        key :operationId, "showExtraProjectDetailsById"
        key :produces,    %w(application/json)

        parameter do
          key :name,     :id
          key :type,     :string
          key :in,       :path
          key :required, true
        end

        response 200 do
          schema do
            key :'$ref', "Project"
          end
        end
      end
    end
  end
end

Multiple APIs

There is a clean way to provide multiple APIs or API versions.

Here is an example of setting up two API versions:

config/routes.rb:

Rails.application.routes.draw do
  namespace :api do
    namespace :v1 do
      crud :projects
      mount_openapi_specification name: :v1
    end

    namespace :v2 do
      crud :projects
      mount_openapi_specification name: :v2
    end
  end

  mount_openapi_documentation
end

config/initializer/openapi.rb:

Openapi.configure do |config|
  config.apis = {
    v1: {
      title: 'Version 1',
      description: 'Legacy API version, please check out Version 2.',
      version: '1.0',
      base_path: '/api/v1',
      controllers: [Api::V1::ProjectsController]
    },
    v2: {
      title: 'Version 2',
      description: 'Latest stable API version.',
      version: '2.0',
      base_path: '/api/v2',
      controllers: [Api::V2::ProjectsController]
    }
  }
end

Controllers with custom logic would be placed at app/controllers/api/v1 and app/controllers/api/v2 modules.

OpenAPI Rails — Multiple versions demo

Contributors

If you have any ideas or questions please feel free to reach out! PRs are welcome, tests are on the roadmap.

OpenAPI Rails gem is maintained and funded by Slate Studio LLC.