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 vehicles
table 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
.
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.
the don
Published on
You could also easily containerize ruby on rails code using docker. You can learn more on docker docs: https://docs.docker.com/guides/ruby/containerize/
Tech Wizard
Published on
I have had great headache hosting rails
the don
• Nov 20, 2024You probably need to learn about docker!
Tutor Juliet
Published on
Rails is outdated, I'd prefer node js ☺️