How to Implement Active Model Serializers with Your Rails API? www.bacancytechnology.com
In this tutorial, we will learn how to make serializers for Rails APIs and implement them efficiently so that they can be accommodated to versioning APIs too.
Table of Content 1. What is Active Model Serializers? 2. Importance and Usage of Active Model Serializers 3. How to Implement Active Model Serializers with Rails API? 4. Alternative of Active Model Serializers 5. Conclusion
What is Active Model Serializers?
Serializer gem allows us to format our JSON easily. It will enable us to select only the data we want and access our relationships with a single request. Active Model Serializers provides a way of creating custom JSON in an objectoriented manner. Active Model Serializer consists of two components: Serializers: It describes which attributes & relationships to be serialized. Adapters: It describes the way of serializing those attributes & relationships, i.e., how to serialize. The serializer creates the relationship in the backend and then translates it to the frontend.
Importance and Usage of Active Model Serializers
Active Model Serializers offers a way to create custom JSON by representing each resource as a class inherited from Active Model Serializers. With the help of a serializer, we need to make a single request to the backend. With proper association done through serialization, the backend will fetch all the required data needed by request rather than requesting multiple times to multiple models. The primary usage of Active Model Serializers is to create custom JSON responses. By default, Rails provides a way to render JSON, but we need a serializer if we want to customize it.
How to Implement Active Model Serializers with Rails API?
Here is the step-by-step guide to implementing Active Model Serializers with Rails API whose source code is available in the Github repository. In this demo, we will be installing two dependencies-
⦿ active_model_serializers gem ○ To achieve the intention of serialization
⦿ faker gem ○ To mock (fill) data Let’s get started with building our demo project for Active Model Serializer.
1. Create new project Create a new project by executing the below-mentioned command rails new active-model-serializer --api
2. Adding Gem Add below gems in your Gemfile active_model_serializers rack-cors faker (development & test environment only) Install these newly added gems using this command $ bundle install
3. Data Modeling Firstly, we will create two models and connect them to One-to-Many relationships. We’ve built an Employee model having attributes (name, email, date_of_birth, mobile_no, designation, salary). Which belongs_to Manager model having the attribute (name).
$ rails g model Manager name $ rails g model Employee name email dob:date mobile designation salary:number manager:references
The Manager has_many employees. At the same time, Employee belongs_to only one manager.
4. Perform Migration After the model changes, migration is necessary. Run the below command $ rails db:migrate
5. Configuration of Routes We will now add routes for APIs-only methods. The routes can extend with other versioning.
# config/routes.rb Rails.application.routes.draw do concern :api_base do resources :employees resources :managers end namespace :v1 do concerns :api_base end end
6. Pre-defined Data Added Declare data seed file to insert mock data for defined models. We can also enter data manually into the database, but it is easy with the seed file by running a single command. $ rails db:seed Here’s the seeds.rb # db/seeds.rb
Employee.destroy_all Manager.destroy_all managers = (1..20).map do Manager.create!( name: "manager" ) end employee = (1..50).map do Employee.create!( name: "employee", email: "emp@gmail.com", dob: "17-01-1988", mobile: "8879544321", designation: "Senior Developer", salary: 35_000, manager: managers.sample ) end
7. Define Model Serializer We will define a serializer for each model indicating what data to be broadcasted over the network by serializing the model. The attribute we declared to be serialized can be further defined to explain what data to be passed for. You can see the below example for the model serializer.
#app/serializers/v1/employee_serialize r.rb
module V1 class EmployeeSerializer < ActiveModel::Serializer attributes :id, :name, :email, :designation, :manager def manager { id: object.manager.id, name: object.manager.name } end end end
#app/serializers/v1/manager_serializer. rb module V1 class ManagerSerializer < ActiveModel::Serializer attributes :id, :name, :employees def employees object.employees.map do |employee| { id: employee.id, name: employee.name, email: employee.email, designation: employee.designation } end end end end
8. Define Controller It’s time to define the controller for respective models to serve serialized objects over API by explicitly defining serializers for individual models. Here, we will define which serializer will be used for passing data by JSON. You can see the below example for controllers.
#app/controllers/v1/employees_controlle r.rb
module V1 class EmployeesController < ApplicationController def index employees = Employee.all.includes(:manager) // used includes method to prevent NQuery problem render json: { data: ActiveModelSerializers::SerializableResou rce.new(employees, each_serializer: EmployeeSerializer),
message: ['Employee list fetched successfully'], status: 200, type: 'Success' } end def show employee = Employee.find(params[:id]) render json: { data: ActiveModelSerializers::SerializableReso urce.new(employee, serializer: EmployeeSerializer), message: ['Employee profile fetched successfully'], status: 200, type: 'Success'
} end end end #app/controllers/v1/managers_controlle r.rb module V1 class ManagersController < ApplicationController def index managers = Manager.all.includes(:employees) render json: { data: ActiveModelSerializers::SerializableReso urce.new(managers, each_serializer: ManagerSerializer),
message: ['Manager list fetched successfully'], status: 200, type: 'Success' } end def show manager = Manager.find(params[:id]) render json: { data: ActiveModelSerializers::SerializableReso urce.new(manager, serializer: ManagerSerializer), message: ['Manager profile fetched successfully'], status: 200, type: 'Success'
} end end end
9. End-point Response The output for the request to fetch details of employees and managers APIs is as shown below. // GET http://localhost:3000/v1/employees/1
{ "data":{ "id":1, "name":"employee", "email":"emp@gmail.com", "designation":"Senior Developer", "manager":{ "id":6, "name":"manager" } }, "message":[ "Employee profile fetched successfully" ], "status":200, "type":"Success" }
// GET http://localhost:3000/v1/managers/6 { "data":{ "id":6, "name":"manager", "employees":[ { "id":1, "name":"employee", "email":"emp@gmail.com", "designation":"Senior Developer" }, { "id":33, "name":"employee", "email":"emp@gmail.com", "designation":"Senior Developer" },
{ "id":39, "name":"employee", "email":"emp@gmail.com", "designation":"Senior Developer" } ] }, "message":[ "Manager profile fetched successfully" ], "status":200, "type":"Success" }
10. Versioning Controller & Serializer We can extend the API and serializers by versioning them. For creating another version of the controller, create it under the path app/controllers/v2/employees_controlle r.rb And for creating the serializer, create it under the path app/serializers/v2/employee_serializer.r b. Remember that the class you’re creating for versioned API should fall under module V2 (or whatever version you’re defining for).
Quick Summary Here is the list of steps we performed to build serializer APIs: Created new project using rails new active-model-serializer --api Added required gems Defined models Migrated the schema Configured routes for the API Defined serializer for the respective model Implemented business logic in the controller Fetched data from API endpoints
Alternative of Active Model Serializers
JSONAPI-RB- It is considered a highly performant and modular JSON:API. There's a vibrant community around it that has produced this Ruby library consisting of four micro-libraries and two frameworks. Fast JSON API- It is a lightning-fast JSON:API serializer for Ruby Objects. It is believed to be 25 times faster than Active Model Serializers. Blueprinter- It is a high-speed, declarative, and API agnostic serializer that uses composable views for reducing duplication.
Conclusion
So, I hope you have a clear understanding of What is Active Model Serializers? Implementation, Usage, and Alternatives of Active Model Serializers in Rails 6. If you are looking for a helping hand in your Ruby on Rails project, then you’ve landed on the right page. Get in touch with us to hire ROR developer with the desired skillset at your ease and convenience.
Thank You
www.bacancytechnology.com