Tìm hiểu về grape API và active model serializers
Bài đăng này đã không được cập nhật trong 3 năm
I. Các khái niệm?
1. Grape API
- Grape là một REST-like API micro-framework cho Ruby. Nó được thiết kế để chạy trên Rack hoặc bổ sung cho mô hình ứng dụng web hiện có như Rails và Sinatra bằng việc cung cấp một DSL đơn giản để dễ dàng phát triển các RESTful API
- Cài đặt:
Thêm dòng này vào Gemfile:
gem 'grape'
Sau đó chạy:
$ bundle install
2. ActiveModel Serializers
- ActiveModelSerializers (AMS) là một gem trong rails hỗ trợ người dùng tạo ra JSON dễ dàng và đơn giản hơn. AMS thực hiện thông qua 2 thành phần: Serializers và Adapter. Serializers mô tả những thuôc tính và các mối quan hệ mà cần được chuyển đổi. Adapter mô tả cách các thuộc tính và các mối quan hệ mà cần chuyển đổi.
- Cài đặt:
Thêm dòng này vào Gemfile
gem 'active_model_serializers'
Sau đó chạy:
$ bundle install
II. Cách sử dụng
1. Grape API
- Tham khảo ở đây: https://viblo.asia/quynhbv_hp/posts/2p1PvQpBGldr. Bài viết trình bày rất rõ về cách sử dụng Grape API
2. ActiveModel Serializers
- Ví dụ khi ta gọi 1 API, cụ thể ở đây là gọi api user detail (current_user):
# lib/api/v1.rb
class API::V1 < Grape::API
version "v1", using: :path
rescue_from Grape::Exceptions::ValidationErrors do
error!({status_code: Settings.http_code.code_400, content: Settings.validations_error},
Settings.http_code.code_400)
end
desc "Return the current API version - V1."
get do
{version: "v1"}
end
helpers do
def authenticate!
error!({content: "401, Unauthorized"}, 401) unless current_user
end
def current_user
@current_user ||= User.authorize!(env)
end
end
mount UsersAPI
end
#lib/api/v1/users_api.rb
class API::V1::UsersAPI < Grape::API
resources :users do
before do
authenticate!
end
namespace :me do
get do
render curent_user, meta {message: "current_user's information"}
end
end
end
end
-
Khi client thông qua url:
http://localhost:3000/api/v1/users/me
, nếu không dùngActiveModel::Serializer
cho modelUser
thì ta sẽ nhận được rất nhiều các attributes từcurrent_user
và tất nhiên nhiều attributes sẽ bị coi là dư thừa nếu phía client không sử dụng đến chúng. VD:Hình ảnh: kết quả trả về khi dùng postman gọi đến API users thông qua url:
http://localhost:3000/api/v1/users/me
Và khi chúng ta dùng đến ActiveModel::Serializer
- Bật terminal lên và
cd
đến thư mực chứa project, chạy:
$ rails g serializer user
ta sẽ được 1 file như thế này:
#app/serializers/user_serializer.rb
class UserSerializer < ActiveModel::Serializer
attributes :id
end
- Khi tạo
user_serializer.rb
thì mặc định attributes trả về dạngJSON
của modelUser
chỉ có:id
, giờ ta sẽ edit nó thành như thế này:
#app/serializers/user_serializer.rb
class UserSerializer < ActiveModel::Serializer
attributes :name, :facebook_id, :birthday, :age, :sex
end
- Thì khi gọi api user qua url
http://localhost:3000/api/v1/users/me
, ta sẽ thu được như thế này: Hình ảnh: kết quả trả về khi dùng postman gọi đến API users thông qua url:http://localhost:3000/api/v1/users/me
=> Ta có thể thấy, các attributes không cần dùng đến hoặc bị thừa đã bị loại bỏ khỏi kết quả trả về.
Using a serializer without render
Nhiều thời điểm chúng ta cần sử dụng dữ liệu dạng JSON của 1 resource nào đó thì ta có thể dùng các cách sau:
- 1 resource:
UserSerializer.new(@user).serializable_hash
=> ta thu được:
=> {:name=>"Phuong", :facebook_id=>"0000000000000", :birthday=>Sun, 30 Nov 1997, :age=>1, :sex=>1}
- arrays resources:
ActiveModel::ArraySerializer.new(@users).as_json
=> ta thu được:
=> [{:name=>"Phuong", :facebook_id=>"0000000000000", :birthday=>Sun, 30 Nov 1997, :age=>1, :sex=>1}, {:name=>"Maximus Rau DVM", :facebook_id=>"0000000000000", :birthday=>Sun, 30 Nov 1997, :age=>1, :sex=>1}]
Overriding association methods
- Nếu muốn override quan hệ nào đó, có thể viết như sau:
class UserSerializer < ActiveModel::Serializer
attributes :name, :facebook_id, :birthday, :age, :sex
has_many :battles
def battles
object.battles
end
end
- Nếu muốn override 1 thuộc tính nào đó thì ta có thể viết như sau:
class UserSerializer < ActiveModel::Serializer
attributes :name, :facebook_id, :birthday, :age, :sex
has_many :battles
def battles
object.battles
end
def age
object.age = 18
end
end
III. Lời kết
- Grape API là 1 công cụ để viết
api
rất đơn giản nhưng mang lại hiệu quả rất cao. - Active Model Serializer khi kết hợp với API thì giúp cho kết quả của trả về API được ngắn gọn dễ hiểu
IV. Tham khảo
All rights reserved