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:
rails 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.
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:
- has_scope via has_scope
- search via mongoid-search
- version via mongoid-history
-
CSV
format forindex
action, requires.csv
format to be added to the request url, e.g./api/posts.csv
.
Customization
In the controller there is a way override default behaviour with helpers:
-
paginates_per(number)
— set page size (default50
) forindex
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.
Related Documents
- OpenAPI ❤️ Rails — tutorial for setting up a new rails project with OpenAPI support.
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.