Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Rswag API Documentation

This project uses Rswag to generate Swagger/OpenAPI documentation for the API.

Setup Complete ✅

The following components have been installed and configured:

  • rswag-api - Serves Swagger JSON/YAML files
  • rswag-ui - Provides Swagger UI interface
  • rswag-specs - RSpec integration for generating docs from tests

Accessing API Documentation

Once the Rails server is running, you can access the API documentation at:

http://localhost:3000/api-docs

File Structure

config/
  initializers/
    rswag_api.rb       # API serving configuration
    rswag_ui.rb        # UI configuration
spec/
  swagger_helper.rb    # Swagger generation configuration
  integration/         # API integration specs for documentation
    example_spec.rb    # Example API spec
swagger/
  v1/
    swagger.yaml       # Generated OpenAPI specification

Writing API Documentation Specs

API documentation specs are written as RSpec integration tests in spec/integration/. Here’s a basic example:

require 'swagger_helper'

RSpec.describe 'Restaurants API', type: :request do
  path '/api/v1/restaurants' do
    get 'List restaurants' do
      tags 'Restaurants'
      produces 'application/json'

      parameter name: :locale, in: :query, type: :string, required: false,
                description: 'Locale (en, th, cn)'
      parameter name: :page, in: :query, type: :integer, required: false

      response '200', 'success' do
        schema type: :object,
               properties: {
                 data: {
                   type: :array,
                   items: {
                     type: :object,
                     properties: {
                       id: { type: :integer },
                       name: { type: :string },
                       location: { type: :string }
                     }
                   }
                 },
                 meta: {
                   type: :object,
                   properties: {
                     current_page: { type: :integer },
                     total_pages: { type: :integer }
                   }
                 }
               }

        # Optionally run actual tests
        run_test! do |response|
          data = JSON.parse(response.body)
          expect(data['data']).to be_an(Array)
        end
      end

      response '401', 'unauthorized' do
        run_test!
      end
    end
  end

  path '/api/v1/restaurants/{id}' do
    parameter name: :id, in: :path, type: :string, description: 'Restaurant ID'

    get 'Get restaurant details' do
      tags 'Restaurants'
      produces 'application/json'
      security [bearer_auth: []]

      response '200', 'restaurant found' do
        schema type: :object,
               properties: {
                 id: { type: :integer },
                 name: { type: :string },
                 description: { type: :string }
               }

        let(:id) { '123' }
        run_test!
      end

      response '404', 'restaurant not found' do
        let(:id) { 'invalid' }
        run_test!
      end
    end
  end
end

Generating Documentation

To generate/update the Swagger documentation from your specs:

# Generate swagger.yaml from integration specs
RAILS_ENV=test bundle exec rake rswag:specs:swaggerize

# Or generate manually by running specs with swagger formatter
RAILS_ENV=test bundle exec rspec spec/integration --format Rswag::Specs::SwaggerFormatter --order defined

This will update swagger/v1/swagger.yaml based on your integration specs.

Authentication in Specs

For endpoints requiring authentication:

path '/api/v1/protected_resource' do
  get 'Protected endpoint' do
    tags 'Protected'
    security [bearer_auth: []]

    parameter name: :Authorization, in: :header, type: :string,
              description: 'Bearer token'

    response '200', 'success' do
      let(:user) { create(:user) }
      let(:token) { generate_jwt_token(user) }
      let(:Authorization) { "Bearer #{token}" }

      run_test!
    end
  end
end

Configuration

API Configuration (config/initializers/rswag_api.rb)

  • Swagger files are served from swagger/ directory
  • Multiple API versions can be configured

UI Configuration (config/initializers/rswag_ui.rb)

  • Currently configured to show API V1 at /api-docs/v1/swagger.yaml
  • Can add basic auth if needed

Swagger Helper (spec/swagger_helper.rb)

  • Defines global metadata (title, version, servers)
  • Configures security schemes (OAuth2, Bearer auth)
  • Sets output format (YAML/JSON)

Adding New API Versions

  1. Update spec/swagger_helper.rb to add a new version:
config.openapi_specs = {
  'v1/swagger.yaml' => { ... },
  'v2/swagger.yaml' => {
    openapi: '3.0.1',
    info: {
      title: 'HungryHub API V2',
      version: 'v2'
    },
    # ... rest of config
  }
}
  1. Update config/initializers/rswag_ui.rb:
c.swagger_endpoint '/api-docs/v2/swagger.yaml', 'API V2 Docs'
  1. Create specs with openapi_spec tag:
describe 'My API', openapi_spec: 'v2/swagger.yaml', type: :request do
  # ...
end

Best Practices

  1. Keep specs organized: Group related endpoints in the same spec file
  2. Use meaningful tags: Help organize endpoints in Swagger UI
  3. Document all parameters: Include type, description, and requirements
  4. Show response schemas: Define clear response structures
  5. Run tests: Use run_test! to ensure specs match actual API behavior
  6. Version your API: Use path versioning (/api/v1/, /api/v2/)

Troubleshooting

Documentation not updating

  • Ensure you’ve run rake rswag:specs:swaggerize after spec changes
  • Check that specs are in spec/integration/ directory
  • Verify spec/swagger_helper.rb is properly configured

UI not loading

  • Ensure Rails server is running
  • Check that routes are properly mounted in config/routes.rb
  • Verify swagger/v1/swagger.yaml exists

Authentication not working in UI

  • Use the “Authorize” button in Swagger UI
  • Enter your Bearer token or OAuth credentials
  • Ensure security schemes are defined in swagger_helper.rb

Resources