# How to generate OpenAPI documentation with Rswag for Ruby on Rails
Source: https://speakeasy.com/openapi/frameworks/rails

When building APIs in a Ruby on Rails application, "Convention over Configuration" is already embraced. Building RESTful routes is standard for most Rails developers, as is writing tests using Test Driven Development (TDD), but creating an OpenAPI document that accurately describes an API can be another matter.

[The OpenAPI Specification](https://swagger.io/specification/) (formerly Swagger) has become the industry standard for documenting RESTful APIs, but manually writing and maintaining OpenAPI documents can be a time-consuming and error-prone process.

[Rswag](https://github.com/rswag/rswag) solves this problem by enabling OpenAPI documents to be generated directly from RSpec tests. This approach helps documentation stay in sync with the actual API implementation.

This guide demonstrates how to:

- Document a Rails API with Rswag's RSpec-based domain-specific language (DSL).
- Generate OpenAPI documents.
- Use the Speakeasy CLI to generate client SDKs.

The guide also covers customization of OpenAPI documents and troubleshooting common issues.

## What is Rswag?

[Rswag](https://github.com/rswag/rswag) is a Ruby gem that helps generate documentation for Rails APIs. Unlike other Ruby gems that add API documentation directly into code with comments or special attributes, Rswag builds API documentation through tests.

The idea behind Rswag is simple: RSpec tests describe API behavior using Rswag's extended rspec-rails OpenAPI-based DSL, and those tests are used to generate OpenAPI documentation. Unlike other tools, this approach tests the application while producing documentation at the same time.

### Wait, what's RSpec?

[RSpec](https://rspec.info/) is a Ruby testing framework used to write tests for code. Specifically, [rspec-rails](https://github.com/rspec/rspec-rails) brings RSpec testing to Rails applications. RSpec has a DSL (Domain Specific Language) that makes tests easy to read and understand. Rswag builds on this with its OpenAPI-based DSL to describe API endpoints and then generate the OpenAPI document from spec tests.

### So, to summarize:

```mermaid
graph TD
    R[(Rails API endpoints)] -->|are defined in| A[RSpec request specs]
    A -->|feed| B[Rswag generator]
    B --> |generate| C[(OpenAPI document)]
```

Rswag has three main parts used in this guide:

- `rswag-specs`: Adds an OpenAPI-based DSL to [RSpec](https://rspec.info/) to describe API endpoints. When these spec tests run, they verify that the API works correctly and collect information for the documentation.
- `rswag-api`: Creates an endpoint in the Rails app that serves the OpenAPI document (in JSON or YAML format) for use by other tools.
- `rswag-ui`: Adds the OpenAPI documentation UI to the app, providing a webpage for viewing and trying out the API.

Rswag keeps documentation aligned with code changes. If the API behavior changes without updated documentation, tests will fail, helping catch documentation errors early. Because the documentation is generated from tests that run against the API, the documented behavior reflects reality.

## Example API repository

The source code for a complete implementation of this guide is available in the [rails-f1-laps-api repository](https://github.com/speakeasy-api/examples/tree/main/frameworks-rails-rswag). Clone the repository to follow along with the tutorial or use it as a reference for a Rails project.

This guide uses a simple Formula 1 (F1) lap times API with the following resources:

- **Drivers**: F1 drivers with their names, codes, and countries
- **Circuits**: Racing circuits with names and locations
- **Lap times**: Records of lap times for drivers on specific circuits

The API allows clients to list all drivers, circuits, and lap times. Query parameters can be used to filter lap times by specific drivers, circuits, and lap numbers, and `POST` requests can be used to create new lap time records.

### Requirements

To follow this guide, the following should be available:

- Ruby on Rails installed
- A Rails API application (the example app provided above can be used)

## Adding Rswag to a Rails application

Begin by adding Rswag to a Rails application. First, add the Rswag gems to the application's Gemfile:

```ruby filename="Gemfile"
group :development, :test do
  gem 'rswag-specs'
end

gem 'rswag-api'
gem 'rswag-ui'
```

The `rswag-specs` gem is needed only for development and testing, while the `rswag-api` and `rswag-ui` gems are required in all environments to allow other tools to interact with OpenAPI specs.

After updating the Gemfile, install the gems:

```bash
bundle install
```

Now, run the Rswag generators to set up the necessary files:

```bash
rails generate rswag:api:install
rails generate rswag:ui:install
rails generate rswag:specs:install
```

These generators create several important files, including:

- `config/initializers/rswag_api.rb`, which configures how the Rails Enginge exposes the OpenAPI files
- `config/initializers/rswag_ui.rb`, which configures the OpenAPI UI and OpenAPI endpoints
- `spec/swagger_helper.rb`, which sets up RSpec for generating OpenAPI specifications
- `config/routes.rb`, configures where Rails mounts Rswag's OpenAPI documentation engine

## Configuring Rswag

With the Rswag components installed, configure them to work with the API.

### Configuring the OpenAPI document generator

The `spec/swagger_helper.rb` file is the central configuration for API documentation.

Here is an example configuration for the F1 Laps API:

```ruby filename="swagger_helper.rb"
RSpec.configure do |config|
  config.openapi_root = Rails.root.to_s + '/openapi'

  config.openapi_specs = {
    'v1/openapi.yaml' => {
      openapi: '3.0.1',
      info: {
        title: 'F1 Laps API',
        version: 'v1',
        description: 'API for accessing Formula 1 lap time data and analytics',
        contact: {
          name: 'API Support',
          email: 'support@f1laps.com'
        },
        license: {
          name: 'MIT',
          url: 'https://opensource.org/licenses/MIT'
        }
      },
      paths: {},
      components: {
        securitySchemes: {
          bearer_auth: {
            type: :http,
            scheme: :bearer,
            bearerFormat: 'JWT'
          }
        }
      },
      servers: [
        {
          url: 'http://{defaultHost}',
          variables: {
            defaultHost: {
              default: 'localhost:3000'
            }
          }
        }
      ]
    }
  }

  config.openapi_format = :yaml
end
```

This configuration defines:

- The location where the OpenAPI files will be generated (`openapi_root`)
- The specification title, version, and description
- Contact information and license details
- Security schemes for authentication, such as JWT bearer tokens
- Server information

### Configuring the OpenAPI UI

The OpenAPI UI can be customized through the `config/initializers/rswag_ui.rb` file, which renders at `<api-url>/api-docs` by default:

```ruby filename="rswag_ui.rb"
Rswag::Ui.configure do |c|
  c.openapi_endpoint '/api-docs/v1/openapi.yaml', 'F1 Laps API V1'

  # UI configuration options
  c.config_object['defaultModelsExpandDepth'] = 2
  c.config_object['defaultModelExpandDepth'] = 2
  c.config_object['defaultModelRendering'] = 'model'
  c.config_object['displayRequestDuration'] = true
  c.config_object['docExpansion'] = 'list'
  c.config_object['filter'] = true
  c.config_object['showExtensions'] = true
  c.config_object['showCommonExtensions'] = true
  c.config_object['tryItOutEnabled'] = true
end
```

### Configuring the OpenAPI files (rswag_api.rb)

The `config/initializers/rswag_api.rb` file configures the root location where the OpenAPI files are served:

```ruby filename="rswag_api.rb"
Rswag::Api.configure do |c|
  c.openapi_root = Rails.root.to_s + '/openapi'
end
```

When using rswag-specs to generate OpenAPI files, ensure both `rswag-api` and `swagger_helper.rb` use the same `<openapi_root>`. Different settings exist to support setups where `rswag-api` is installed independently and OpenAPI files are created manually.

## Writing Rswag documentation specs

The most powerful feature of Rswag is the ability to generate OpenAPI documentation directly from RSpec tests. These tests not only verify API functionality but also produce detailed OpenAPI documentation. The following sections show how to write these OpenAPI documents for different endpoints.

### Documenting a simple endpoint

Let's start with a simple health check endpoint that returns basic API status information:

```ruby filename="health_spec.rb"