Building a Ruby on Rails API
What is Ruby on Rails API?
Rails is a web-application framework that includes everything needed to create database-backed web applications according to the Model-View-Controller (MVC) pattern.
Understanding the MVC pattern is key to understanding Rails. MVC divides your application into three layers: Model, View, and Controller, each with a specific responsibility.
Creating Rails API
First, open a terminal application and run:
rails new our-api --api && cd our-api
By passing --api
Rails will not generate any views
in case we run a scaffold migration.
Now open our-api
in a text editor or IDE of your choice and navigate to config/routes.rb
to create our first route. Add the following:
Rails.application.routes.draw do
get 'api/vehicles', to: 'application#vehicles'
end
Now open app/controllers/application_controller.rb
and paste the following code snippet:
class ApplicationController < ActionController::API
def vehicles
render json: { name: 'Tesla Model 3' }
end
end
At this point it’s worthwhile to test it out to make sure everything is set up correctly. To start the server simply run:
rails s
If the browser you’re using supports rendering JSON, just open http://localhost:3000/api/vehicles
in your browser directly.
Alternatively, I recommend using Postman or Insomnia.
The response should be following:
{
"name": "Tesla Model 3"
}
Seed the database
In this exercise we’ll use SQLite for the database, this means it’s just a file within our project — it won’t require a server or host. Rails migrations can be run to actually interact with the DB.
In your terminal run the following:
rails g model Vehicle name:string price:decimal{10-2} picture:text
What does this do? It generates a model called Vehicle
and 3 fields in the database: name
, price
and picture
.
Now run the following:
rake db:migrate
Now open application_controller.rb
and add the following:
class ApplicationController < ActionController::API
def vehicles
@vehicles = Vehicle.all render json: @vehicles
end
end
If you hit the api/vehicles
endpoint, is should return an empty array []
. This is expected; no data exists in the database yet. To add data, open db/seeds.rb
. You’ll see that there’s already some examples there, but we’ll need to delete these and add our own:
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' },
{ 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' },
{ 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' },
{ 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' }
])
You might notice the picture
URLs are quite long, we’re actually using the static image assets from the Tesla website. Now we can seed the database. To do this, run:
rake db:seed
Now if you hit api/vehicles
it should return the 4 entries.
Routes
It’s practical and foreseeable that you’ll want to add more API resources, say locations
, events
and services
. In this scenario, the routes.rb
file would look like this:
Rails.application.routes.draw do
get 'api/vehicles', to: 'application#vehicles'
get 'api/locations', to: 'application#locations'
get 'api/events', to: 'application#events'
get 'api/services', to: 'application#services'
end
You probably notice each endpoint is repetitively prefaced with api/
. This can be refactored for simplicity and readability scoping the routes.
Rails.application.routes.draw do
scope :api do
get 'vehicles', to: 'application#vehicles'
get 'locations', to: 'application#locations'
get 'events', to: 'application#events'
get 'services', to: 'application#services'
end
end