Building and Documenting REST API in Rails

October 26, 2015
admin

Contributor: Nahid Ebne Hasan, Software Engineer, Nascenia

Representational State Transfer known as REST is the software architectural style for the web. The architecture is used for giving flexibility to retrieve data through some endpoints. REST API runs over HTTP protocol.

Building REST API in Rails is more fun than other frameworks, easy, clean and clear to understand. Also, REST API needs some clean documentation as the endpoints will be used by the others. REST API in Rails

Today, I am going to demonstrate a very basic example of building REST API in Rails and document them. You can find some useful gem over the internet which will help you building REST API in Rails and documenting. But I am going to demonstrate scratch REST API building in rails.

Example application API overview

We are going to create a Rails application that has some users and users have some posts that can be created updated and deleted by the users using the authentication token. For simplicity we will skip the registration portion. In REST API mainly CRUD operations (CREATE, UPDATE and DELETE) are performed. So, we will perform these three types of operation in our example.

We assume we have the fully functional new rails app created and rails environment installed. If you don’t have then follow this link to install rails environment and create a new rails app.

Creating new rails app

Following command will create a new rails app

$ rails new api_rails -d mysql

I am going to use mysql as app database. If you want to use other database system then skip “-d mysql” portion.

After necessary gem and bundle installation we will create some models and controllers. We will create controllers for API. These controllers will be used only for API calls. Before that we need to create some extra directories under app/controllers.

$ cd api_rails/app/controllers
$ mkdir api
$ cd api
$ mkdir v1

We will generate API controllers under v1 directory. Another important thing is REST API is consistent after release. You cannot change them as they will be used and implemented on others application. In that case, versioning is necessary for API to maintain new changes.

Generating Models
$ rails generate model user user_name:string email:string password:string auth_token:string
$ rails generate model post description:text user_id:integer
$ rake db:migrate
Generating Controllers
$ rails generate controller api::v1::users
$ rails generate controller api::v1::posts

Modify the users controller
/app/controllers/api/v1/users_controller.rb

class Api::V1::UsersController < ApplicationController
    def index
        @users = User.all
        render json: @users
    end
  
    def request_token
        @user = User.where('email = ? AND password = ?', params[:email], params[:password]).first
        if @user.present?
            render json: {token: @user.auth_token, info: 'Use your token to make api calls'}
        else
            render json: {error: 'User not Found'}
        end
    end
end

Modify the posts controller
/app/controllers/api/v1/posts_controller.rb

class Api::V1::PostsController < ApplicationController
    before_filter :verify_token
    def index
        @posts = Post.all
        render json: @posts
    end
    def create
        @post = Post.new(user_id: session[:user_id], description: params[:description])
        if @post.save
            render json: @post
        else
            render json: {error: 'process not completed'}
        end
    end
    def update
        @post = Post.where(id: params[:id], user_id: session[:user_id]).first
        if @post.update_attribute(:description, params[:description])
            render json: @post
        else
            render json: {error: 'process not completed'}
        end
    end
    def destroy
        @post = Post.where(id: params[:id], user_id: session[:user_id]).first
        if @post.destroy
            render json: {status: 'successful'}
        else
            render json: {error: 'process not completed'}
        end
    end
end

Modify the application_controller
/app/controllers/application_controller.rb

class ApplicationController < ActionController::Base 
    # Prevent CSRF attacks by raising an exception. 
    # For APIs, you may want to use :null_session instead. 
    protect_from_forgery with: :exception 
    protect_from_forgery with: :null_session, :if => Proc.new { |c| c.request.format == 'application/json' }
    def verify_token
        if params[:token].present?
            user = User.where('auth_token = ?', params[:token]).first
            if user.present?
                return session[:user_id] = user.id
            else
                render json: {error: 'Authentication error. Authentication token is not recognized'}
            end
        else
            render json: {error: 'Authentication error. Authentication token is necessary'} 
        end
    end
end
Writing Routes

Modify the routes.rb file
config/routes.rb

Rails.application.routes.draw do
    namespace :api do
        namespace :v1 do
            get 'users/request_token', to: 'users#request_token'
            resources :users
            resources :posts
        end
    end
end

For simplicity, I am going to skip registration part for our sample API example. But remember registration and authorization are important for API calls.

Now assume we have an user registered in our system with the following credentials. And an auth_token generated by the system for that user.

user_name: xyz
email: xyz@gmail.com
password: 123
auth_token: kxly

We will create a request_token API call to get a token with the above credential which will be needed for further API call processing, as because every API call will be verified by the token generated by the request_token API call. That’s why we implemented a method verify_token in application_controller.rb

Documenting API

We need to document our APIs properly so that anyone can understand easily and use our API endpoints or integrate our API to their application to retrieve data.

Request for an authentication token
url: api/v1/users/request_token
method: ‘GET’
parameters body: email [required], password [required]

Get all posts
url: api/v1/posts
method: ‘GET’
parameters body: token [required]

Creating a new post
url: api/v1/posts
method: ‘POST’
parameters body: token [required], description [required]

Updating a post
url: api/v1/posts/:id
method: ‘PUT’
parameters body: token [required], description [required]

Deleting a post
url: api/v1/posts/:id
method: ‘DELETE’
parameters body: token [required]

To perform every API call we also need a REST-client application. Chrome has a popular extension named “POSTMAN”. Install and open it to execute API calls.

Sample API calls

First call for request a token
method: ‘GET’
url: localhost:3000/api/v1/users/request_token

Parameters list
email: xyz@gmail.com
password: 123

Generated url would be the following
localhost:3000/api/v1/users/request_token?email=xyz@gmail.com&password=123

Result

{
    “token”: “kxly”,
    “info”: “Use your token to make api calls”
}

Now using that token “kxly” we can make all the API calls. Every response format is json here. Other format can be possible like XML format.

Second call to create a post
method: ‘POST’
url: localhost:3000/api/v1/posts

Parameters list
token: kxly
description: Building and Documenting REST API in Rails

Generated url would be the following
localhost:3000/api/v1/posts?token=kxly&description=Building and Documenting REST api in Rails

Result

{
    "id": 1,
    "user_id": 1,
    "description": "Building and Documenting REST API in Rails",
    "created_at": "2015-09-20T15:46:26.000Z",
    "updated_at": "2015-09-20T16:00:41.375Z"
}

Third call to update a post
method: ‘PUT’
url: localhost:3000/api/v1/posts/1
N.B: Here /1 is the id of the post we have just created before. Update call needs an identification of which post we should update

Parameters list
token: kxly
description: Building and Documenting REST api in Rails updated

Generated url would be the following
localhost:3000/api/v1/posts?token=kxly&description=Building and Documenting REST api in Rails updated

Result

{
    "id": 1,
    "user_id": 1,
    "description": "Building and Documenting REST API in Rails updated",
    "created_at": "2015-09-20T15:46:26.000Z",
    "updated_at": "2015-09-20T16:00:41.375Z"
}

Fourth call delete a post

method: ‘DELETE’
url: localhost:3000/api/v1/posts/1

Parameters list
token: kxly

Generated url would be the following
localhost:3000/api/v1/posts?token=kxly

Result

{
    "status": "successful"
}

Nowadays developers build API to their most of the web application, to give better performance to the users and also other developers. So building API and then most significant job is to write documentation properly for the API endpoints behavior. In Rails, both job can be done very easily and without any pain usually developers feel on working with other frameworks.

3 Comments. Leave new

Nice blog. Love the way it is showcased in simple steps.

Reply
Ritesh Katare
March 15, 2017 5:19 pm

Really helpful to understand REST API with Rails step by step.

Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.