manual of building a rails app powered with rswag and postgresql and deployed on Heroku

2 min read

This is going to be a guide about how to combine Ruby On Rails with rswag. Rswag can generate beautiful API documentation, including a UI to explore and test operations, directly from your rspec integration tests.

prerequisite

  • Rails 6+
  • postgresql installed
  • A Heroku user account

create a api-only rails app with postgresql support

$ rails new project_name --api --database=postgresql

install rswag

add these lines to your Gemfile:

# Gemfile
gem 'rspec-rails'
gem 'rswag'

Install the gem and use task from them to generate files needed: bundle install rails g rswag:install rails g rspec:install

generate scaffold

rails g scaffold User name:string password:string email:string phone_number:string

create spec file

Create an integration spec to describe and test your API.

#spec/integration/user_spec.rb
require 'swagger_helper'

describe 'Users API' do

  path '/users' do

    post 'Creates a user' do
      tags 'Users'
      consumes 'application/json', 'application/xml'
      parameter name: :user, in: :body, schema: {
        type: :object,
        properties: {
          name: { type: :string },
          password: { type: :string },
          email: { type: :string },
          phone_number: { type: :string }
        },
        required: [ 'name', 'password' ]
      }

      response '201', 'user created' do
        let(:user) { { name: 'foo', password: 'bar' } }
        run_test!
      end

      response '422', 'invalid request' do
        let(:user) { { name: 'foo' } }
        run_test!
      end
    end
  end

  path '/users/{id}' do

    delete 'Delete a user' do
      tags 'Users'
      consumes 'application/json', 'application/xml'
      produces 'application/json', 'application/xml'
      parameter name: :id, :in => :path, :type => :string
      
      response '200', 'User deleted' do
        let(:id) {create(:user).id}

        run_test!
      end
    end
  end

  path '/users' do

    get 'Retrieves all users' do
      tags 'Users'
      produces 'application/json', 'application/xml'
      
      response '200', 'user found' do
        schema type: :object,
          properties: {
            id: { type: :integer },
            name: { type: :string },
            password: { type: :string }
          },
          required: [ 'id', 'name', 'password' ]

        let(:id) { User.create(name: 'foo', password: 'bar').id }
        run_test!
      end
    end
  end

  path '/users/{id}' do

    get 'Retrieves a user' do
      tags 'Users'
      produces 'application/json', 'application/xml'
      parameter name: :id, :in => :path, :type => :string

      response '200', 'user found' do
        schema type: :object,
          properties: {
            id: { type: :integer },
            name: { type: :string },
            password: { type: :string }
          },
          required: [ 'id', 'name', 'password' ]

        let(:id) { User.create(name: 'foo', password: 'bar').id }
        run_test!
      end

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

      response '406', 'unsupported accept header' do
        let(:'Accept') { 'application/foo' }
        run_test!
      end
    end
  end
end

rswag do not support openapi 3.x now, so make sure use swagger: '2.0' in swagger_helper.rb.

add settings for postgresql

In config/database.yml, under default: &default, add:

host: localhost
username: postgres
password: (the password you created during postgresql installation)
port: 5432

Then in your terminator run rake db:create:all(don’t worry if you encountered the same problem here) and then run rake db:migrate, restart your rails server and your app should now work.

Generate the Swagger JSON or YAML file(s)

rails db:migrate RAILS_ENV=test rake rswag:specs:swaggerizealso aliased as rake rswag Spin up your app rails s and check out the awesome, auto-generated docs at /api-docs!