how to build secure apis with ruby on rails
user profile avatar
tech girl

Published on • 🕑6 min read

A Detailed Guide on How to Create Ruby on Rails Application (API)

1likes1

Blog views465

Listen to this blog

If you know me well, I am that ruby girl that enjoys working with ruby on rails. As a language designed to make developers happy, rails surely offer alot of flexibility to developers, including some generators that can generate anything with just one line of code! This guide will discuss how to create a ruby on rails api, assuming you have rails installed.

Ruby on Rails API refers to the application programming interface (API) framework provided by the Ruby on Rails (Rails) web application framework. It allows developers to build and expose APIs for their web applications efficiently.

Why Choose Rails for API Development?

1. ActiveRecord ORM

Rails includes ActiveRecord, a robust Object-Relational Mapping (ORM) system that simplifies database interactions. It allows you to work with databases using Ruby objects and eliminates the need to write complex SQL queries for most operations.

2. Convention Over Configuration

Rails is built around the principle of "Convention Over Configuration," meaning it provides sensible defaults, reducing the decision-making and configuration developers need to do.

3. Rich Ecosystem of Gems

Rails has a vast ecosystem of gems (libraries) that extend its functionality. Whether you need authentication, background processing, or payment integration, there’s likely a gem that fits your needs.

4. Scaffolding

Rails provides generators that can create models, controllers, views, and even tests for you. This feature helps to quickly spin up resources, allowing you to focus more on building the core functionality of your application.

5. Built-in Security Features

Rails includes many security features, such as protection against SQL injection, Cross-Site Scripting (XSS), and Cross-Site Request Forgery (CSRF).

Step-by-Step Guide to Building an API

For this tutorial, we are going to build a simple ruby API for Tesla that returns a list of their vehicle models with the model name, year of manufacture, picture, and price.

Step 1: Create a New Rails Project

Assuming you have installed ruby on rails, open the terminal and run:

rails new tesla --api --skip-test-unit && cd tesla

If you do not have rails installed, see here how to install or run the following command:

gem install rails

2. Generating the Vehicle Model and Controller

Next, we need to leverage the power of rails to scaffold models and get started quicker. Rails come with different commands, which you can view by running rails --help. One of those commands is rails generate which uses rails generator to create assets model routes channel controller generator based on existing templates.

We will create our model, controller, and routes using the rails generator to make things easier.

rails generate scaffold Vehicle name:string year_of_manufacture:integer price:decimal picture:string --no-test-framework

This command will create:

  • A Vehicle model with attributes: name, year_of_manufacture, price, and picture.
  • A VehiclesController with all the standard RESTful actions.
  • The necessary routes for the vehicles resource

3. Running Migrations

Out of the box, rails works with SQLite3 database and thus you need to ensure you have it installed or provide an alternative database such as Postgres when setting up the app. You can also edit the database.yaml file to add your database URL. For this scenario, we will work with the default database.

We need to use rails:migrate to run migrations for our database using activerecord. Rails will automatically create a database for you if it does not exist and create vehiclestable with the specified columns.

rails db:migrate

Step 4: Creating Seed Data 🌱 (Optional)

To populate your database with some initial data, you can create a seed file. Rails provides a convenient way to seed the database with data you can use for testing or development. To add data, open db/seeds.rb. You’ll see that there are already some examples there, but we’ll need to delete these and add our own:

Here is a sample seed data:

Vehicle.create!([
  { name: 'Tesla Model S', price: '51885.17', picture: 'https://static-assets.tesla.com/configurator/compositor?&options=$MT337,$PPSW,$W40B,$IBB1&view=STUD_FRONT34&model=m3&size=1920&bkba_opt=2&version=v0028d202109300916&crop=0,0,0,0&version=v0028d202109300916', year_of_manufacture: 2012 },
  { name: 'Tesla Model 3', price: '100990', picture: 'https://static-assets.tesla.com/configurator/compositor?&options=$MTS10,$PPSW,$WS90,$IBE00&view=FRONT34&model=ms&size=1920&bkba_opt=2&version=v0028d202109300916&crop=0,0,0,0&version=v0028d202109300916', year_of_manufacture: 2017 },
  { name: 'Tesla Model X', price: '120990', picture: 'https://static-assets.tesla.com/configurator/compositor?&options=$MTX10,$PPSW,$WX00,$IBE00&view=FRONT34&model=mx&size=1920&bkba_opt=2&version=v0028d202109300916&crop=0,0,0,0&version=v0028d202109300916', year_of_manufacture: 2015 },
  { name: 'Tesla Model Y', price: '65000', picture: 'https://static-assets.tesla.com/configurator/compositor?&options=$MTY07,$PPSW,$WY19B,$INPB0&view=FRONT34&model=my&size=1920&bkba_opt=2&version=v0028d202109300916&crop=0,0,0,0&version=v0028d202109300916', year_of_manufacture: 2020 }
])

Then, run the seed file to populate your database:

rails db:seed

Step 5: Customizing the Controller

The rails generate command automatically generates a controller with all the methods. However, we need some additional modifications to rescue from activerecord errors and also restrict the types of params we accept when creating a new vehicle.

Navigate to /app/controllers/vehicle_controller.rb and add the following code:

class VehiclesController < ApplicationController
  rescue_from ActiveRecord::RecordNotFound, with: :render_not_found
  rescue_from ActiveRecord::RecordInvalid, with: :render_unprocessable_entity
  # GET /vehicles
  def index
    @vehicles = Vehicle.all
    if params[:name].present?
      @vehicles = @vehicles.where(name: params[:name])
    end
    if params[:year_of_manufacture].present?
      @vehicles = @vehicles.where(year_of_manufacture: params[:year_of_manufacture])
    end
    if params[:price].present?
      begin
        @vehicles = @vehicles.where(price: params[:price])
      rescue ArgumentError
        render json: { error: 'Invalid price parameter' }, status: :bad_request
        return
      end
    end
    render json: @vehicles
  end
  # GET /vehicles/:id
  def show
    @vehicle = Vehicle.find(params[:id])
    render json: @vehicle
  end
  # POST /vehicles
  def create
    @vehicle = Vehicle.create!(vehicle_params)
    render json: @vehicle, status: :created
  end
  # PATCH/PUT /vehicles/:id
  def update
    @vehicle = Vehicle.find(params[:id])
    @vehicle.update!(vehicle_params)
    render json: @vehicle
  end
  # DELETE /vehicles/:id
  def destroy
    @vehicle = Vehicle.find(params[:id])
    @vehicle.destroy!
    head :no_content
  end
  private
  def vehicle_params
    params.require(:vehicle).permit(:name, :year_of_manufacture, :price, :picture)
  end
  def render_not_found
    render json: { errors: ['Vehicle not found'] }, status: :not_found
  end
  def render_unprocessable_entity(invalid)
    render json: { errors: invalid.record.errors }, status: :unprocessable_entity
  end
end

This sample has been modified with extra safety and error handling when a record is not found or cannot be created. The index action has also been updated to handle query parameters for filtering the results. It also includes error handling for invalid price parameters.

Step 5: Start the Server and Get the Data

While you could have started the server earlier on by running rails s, the page would only show the welcome page for rails. Now since we have data, start the server and go to /vehicles to make a get request and return the list of vehicles.

rails s
#test with curl
curl http://localhost:3000/vehicles

You can also test the API using postman or thunderbird extension in vs code for the get, create, update and delete commands. Furthermore, you can debug or even create new vehicles in the database in the rails console by running rails c

ruby-on-rails image

Step 6: Modifying Routes

Rails can display a list of all created routes if you run rails routes, which is useful for tracking down routing problems in your app, or giving you a good overview of the URLs in an app you're trying to get familiar with.

You also have the freedom of renaming your routes any way you like, for example instead of the create route for users, you can rename the route signup and then map it to the users create controller. We can do this by modifying the config/routes.rb file.

Here is an Example:

Rails.application.routes.draw do
  resources :vehicles
  resources :users
  post '/signup', to: 'users#create'
  # Defines the root path route ("/")
end

Step 7: Serializing data

We all know it is annoying to return irrelevant data such as created_at_date and updated_at_date in API requests unless we need such data. Luckily, ActiveModel::Serializer allows us to state which data we want to return in our API requests, thus making the response time even faster.

To use the gem, we need to add it to the gem file and run bundle install. The bundle install command in ruby on rails projects is used to install the necessary gems (ruby libraries or packages) specified in the project’s Gemfile.

gem 'active_model_serializers'
bundle install

Next, we need to generate a serializer for our desired model, which in this case is the vehicle model. Remeber to use Capitalization while referring to a model and lowercase when referring to the table. For example, the model is named Vehicle while its associated table in the database is named vehicle

rails generate serializer Vehicle

This will create a file app/serializers/vehicle_serializer.rb. Update this file to specify the attributes you want to include in the JSON response:

class VehicleSerializer < ActiveModel::Serializer
  attributes :id, :name, :year_of_manufacture, :price, :picture
end

Conclusion

With Rails, creating a RESTful API is both efficient and enjoyable. Its built-in features like ActiveRecord, the rich ecosystem of gems, and the convention-over-configuration philosophy make Rails a powerful tool for building APIs. In this guide, we’ve built a simple Tesla API, showcasing how easy it is to get up and running with Rails.

There is much more about rails that I have not covered here but this can get you going in no time. Hope you enjoyed this tutorial.

Resources

  1. Getting started with ruby on rails [external link]
  2. Ruby on Rails API tutorial [youtube]

Like what you see? Share with a Friend

1 Comments

1 Likes

Comments (1)

sort comments

Before you comment please read our community guidelines


Please Login or Register to comment

user profile avatar

Tutor Juliet

Published on

Rails is outdated, I'd prefer node js ☺️