Beginner’s Guide to Building a Rails API

Koray Ozkal
The Startup
Published in
7 min readOct 23, 2020

--

Building an API from scratch for a web application might sound challenging for a first-timer. But if you have the fundamental Ruby on Rails knowledge, you might even find it easier than you expected.

What is an API?

Rails can serve as both the front-end and back-end of a website. It can also be configured specifically to work just as an API. So what is an API? Basically, API(Application Programming Interface) is a way for one system to communicate with other external systems. As perfectly explained on Ruby on Rails guides, when people say they use Rails as an “API”, it means developers are using Rails to build a back-end that is shared between their web application and other native applications. The reason most developers use Rails is that it provides a set of defaults that allows us to get up and running quickly. That is why instead of using Rails to generate view files that communicate with the server through forms and links, many developers are treating their web application as just an API client that responds with JSON. So when we are following principles to build an M-V-C structure (Model-View-Controller), rails is only in charge of our models and controllers.

So how we can start setting up our Rails API? Currently, I am working on a JavaScript project. We are tasked to set our back-end with Rails API and I will code along with each step with you as the article continues to create an API-only Rails build from scratch.

STEP 1 — CREATE A NEW RAILS APP AS AN API

First and foremost we need to set up our new Rails app environment by flagging it as an API. Now on your terminal, you can follow the format below.

rails new <your_app_name> --api

Have you noticed the API flag we used to specify this is just an API?

--api    #this is the api flag.

You may ask the reason. Remember, we mentioned Rails will only be used for our models and controller. Therefore, --api flag will allow Rails to remove a lot of default features and middleware that will not be needed. Now controllers will inherit from ActionController::API instead of ActionController::Base and generators will not create views.

I am building a comicbook app to list my comicbook collection so let’s start my app setup

rails new comics_geek_backend --api

Also, I would like to share a helpful tip I came across while watching project built videos: If you are planning to deploy your app to an environment like Heroku, the best practice is to generate a new rails project using Postgresql as the database(Make sure to download and run Postgres on your computer.).

rails new comics_geek_backend --database=postgresql --api

STEP 2— Configure CORS to allow frontend to make requests

CORS is designed to prevent scripts like fetch() from one origin accessing a resource from a different origin unless that resource specifically states that it expects to share. However, while working on our API, we want to have our Rails server running while trying out endpoints using fetch(). By using the API flag, the Gemfile was altered to include the rack-cors gem which is commented out initially. So let’s go ahead and uncomment our rack-cours gem in our Gems.

gem 'rack-cors'

We can now go back to our terminal and run bundle install.

run bundle install

In order to get rack-cors working, once the gem is installed, we need to uncomment the following code in config/initializers/cors.rb file .

Rails provides the cors.rb file specifically for defining our rules for cross-origin HTTP requests. The new rails app comes with the string “example.com”. The string after origins specifies which hosts will be allowed to make requests to your API. Now we need to change it to “*” to allow all hosts for our simple Rails API.

STEP 3— Planning Models

Now, let’s plan our Models. For my Comicbook app, I want to build two models. The first one is a Comicbook model that belongs_to a :publisher and a Publisher model that has_many :comicbooks with the attributes below:

Comicbook — has a title, number, artist, writer, image_url so we can add covers and a description.

Publisher — has only a name

Now we can start using rails generator to create our models. If you would like to have a cheat sheet to check how you can build a rails generator, you can also check my previous article here => RUBY ON RAILS GENERATORS: HOW TO GET YOUR APP UP AND RUNNING & START A NEW RAILS PROJECT.

STEP 3 — Generate Models and Create Database

I will go ahead and type the generators below to my terminal. rails will default to string if we don't specify a type for our attributes.

rails g model Publisher name --no-testframeworkrails g model Comicbook title description image_url publisher_id:integer number:integer artist writer --no-testframework

Then we have to run rails db:create && rails db:migrate

This will create two migrations and two models and with minimal seed data. Now, we can even test if everything is working as expected!

STEP 4 — Create Seed Data and Test your associations

Now let’s go to our seeds file db/seeds.rb and create publishers and some comicbooks to start with.

marvel = Publisher.create(name: "Marvel Comics")dc = Publisher.create(name: "DC Comics")image= Publisher.create(name: "Image Comics")Comicbook.create(title: "Amazing Spider-man", number:1, description: "Peter Parker tries to continue a show biz career as Spider-Man, yet J. Jonah Jameson's editorials slamming him as a menace makes it hard to find work.", image_url: "https://images-na.ssl-images-amazon.com/images/S/cmx-images-prod/Item/562/DIG000136._SX360_CLs%7C360,508%7Ccu/cmx-cu-sash-lg.png%7C0,0,361,509%20208,356,152,152_QL80_TTD_.jpg", artist: "Steve Ditko",  writer: "Stan Lee" , publisher_id: marvel.id)Comicbook.create(title: "Flash Rebirth", number: 1, description: "Geoff Johns and Ethan Van Sciver, the writer/artist team behind the blockbuster GREEN LANTERN: REBIRTH and THE SINESTRO CORPS WAR, create an explosive, jaw-dropping epic that reintroduces Barry Allen as The Flash in this volume collecting the fast-paced 6-issue miniseries. But how will this greatest of all Flashes find his place in the twenty-first century?", image_url: "https://images-na.ssl-images-amazon.com/images/S/cmx-images-prod/Item/48457/DIG010147_1._SX360_QL80_TTD_.jpg",  artist: "Ethan Van Sciver",  writer: "Geoff Johns" , publisher_id: dc.id)Comicbook.create(title: "Darkness", number: 1, description: "Coming of Age Introducing mafia hitman Jackie Estacado and the ancient power of the Darkness!Jackie Estacado is assaulted by a host of Angelus warriors who attempt to catch him in a vulnerable state. Their goal is to destroy the Darkness forever.", image_url: "https://images-na.ssl-images-amazon.com/images/S/cmx-images-prod/Item/1166/ICO000034._SX312_CLs%7C312,473%7Ccu/cmx-cu-sash-lg.png%7C0,0,313,474%20160,321,152,152_QL80_TTD_.jpg", artist: "Mark Silvestri",  writer: "Mark Silvestri" , publisher_id: image.id)

Let’s test the associations on our rails console by typing rails c

2.6.1 :012 > spiderman = Comicbook.firstComicbook Load (0.5ms)  SELECT "comicbooks".* FROM "comicbooks" ORDER BY "comicbooks"."id" ASC LIMIT $1  [["LIMIT", 1]]=> #<Comicbook id: 1, title: "Amazing Spider-man", description: "Peter Parker tries to continue a show biz career a...", image_url: "https://images-na.ssl-images-amazon.com/images/S/c...", publisher_id: 1, number: 1, artist: "Steve Ditko", writer: "Stan Lee", created_at: "2020-10-19 20:51:45", updated_at: "2020-10-19 20:51:45">2.6.1 :013 > spiderman.title=> "Amazing Spider-man"2.6.1 :014 > spiderman.artist=> "Steve Ditko"2.6.1 :015 > spiderman.description=> "Peter Parker tries to continue a show biz career as Spider-Man, yet J. Jonah Jameson's editorials slamming him as a menace makes it hard to find work."

Yay!!!!

STEP 5— Generate Controllers

We have our migrations and models set so let’s create our controllers.

rails g controller Comicbooks  
rails g controller Publishers

We can create all the actions we want. So as an example I would like to build an index action for our app/controllers/comicbooks_controller.rb

class ComicbooksController < ApplicationController  

def index
comicbooks= Comicbook.all
render json: comicbooks
end
end

STEP 6 — Create Routes

Ok, we are almost there! Let’s go to config/routes.rb and set up our route for the index action.

class ComicbooksController < ApplicationController  

Rails.application.routes.draw do
resources :comicbooks, only: [:index]end

STEP 7— Test it!

After we complete the rest of the controller actions and related routes, we can go ahead and run our rails server by simply typing rails sand go to localhost:3000/comicbookson our browser, we will be able to see our API in action! Yes, we made it!!

--

--

Koray Ozkal
The Startup

Marketing Strategist @Intel, Tech Blogger, Rock Guitarist, Hockey & Basketball fan.