Rails API with ruby - Grape
GIỚI THIỆU CHUNG API là viết tắt của Application Programming Interface (giao diện lập trình ứng dụng). Nó là 1 giao tiếp phần mềm được dùng bởi các ứng dụng khác nhau. Đây là xu hướng phát triển các ứng dụng có thể hoạt động trên các thiết bị khác nhau phù hợp với nhiều nhu cầu người dùng như ...
GIỚI THIỆU CHUNG
API là viết tắt của Application Programming Interface (giao diện lập trình ứng dụng). Nó là 1 giao tiếp phần mềm được dùng bởi các ứng dụng khác nhau.
Đây là xu hướng phát triển các ứng dụng có thể hoạt động trên các thiết bị khác nhau phù hợp với nhiều nhu cầu người dùng như mobile, website .... Những ứng dụng kiểu này giúp nhà phát triển tiết kiệm tài nguyên cả phần cứng lẫn phần mềm, phát triển ứng dụng linh hoạt hơn và có sự liên kết chặt chẽ giữa các bên.
Ứng với framework Ruby on Rails có rất nhiều cách để xây dựng một API hoàn chỉnh. Tuy vậy trong bài viết này xin được giới thiệu gem ruby-grape vì tính tiện dụng và sự chuyện nghiệp của nó.
CÀI ĐẶT RUBY - GRAPE
Cài đặt ruby-grape tương tự như những gem khác.
- Thêm gem vào Gemfile:
gem "grape" gem "grape-active_model_serializers"
- Chạy lệnh bundle install
=> Có thể thấy gem sẽ tự động sinh ra một thư mục app/api tất cả code API sẽ được khai báo trong thư mục này.
VIẾT ĐẶC TẢ API
Đây là một phần rất quan trọng khi xây dựng một API hoàn chỉnh, tuy vậy nhiều lập trình viên thường lao đầu vào code ngay và bỏ qua bước này. Đây là tài liệu đặc tả API sẽ giúp người xem (ngoài lập trình viên) hiểu đc API đó phục vụ mục đích gì và cách nó hoạt động.
Không cần quá đi sâu vào chi tiết từng phần nhỏ nhặt tuy vậy tài liệu cũng nên có những phần cơ bản sau:
- Đường URL
- Method
- Mục đích viết API
- Input
- Output (normal)
- Putput (errors)
- List errors number
XÂY DỰNG API WITH RUBY - GRAPE
Tiếp theo chúng ta sẽ đi xây dựng một API demo với đặc tả như sau:
-
Đường URL
http://{servername}access_history/update
-
Method
POST
-
Mục đích viết API
Nhận về lịch sử login lần cuối của user.
-
Input
- user_id - access_history
-
Output (normal)
- status: true - number_code: 9999
-
Otput (errors)
- number_code + reason
-
List errors number
- 899: Không được phép là ngày trong tương lai - 900: Tham số truyền vào không đúng kiểu dữ liệu - 901: User truyền vào không tồn tại - 902: Access history fail.
1. Đường dẫn tới thư mục API
- app/api/v1
2. Tạo ra file sau: app/api/v1/api.rb với nội dung
class API < Grape::API prefix "api" version "v1", using: :path mount Demo::V1::AccessHistory end
Đây là file base của toàn bộ API có thể hiểu nó giống như file routes.rb trong Rails.
3. Tạo ra module sau: app/api/v1/validation_rescue.rb với nội dung
module ValidationRescue extend ActiveSupport::Concern SUCCESS_CODE = "9999" included do before do header[I18n.t("api.number_code")] = SUCCESS_CODE end rescue_from Grape::Exceptions::ValidationErrors do error!(Settings.validate_api_error_not_type.to_h, Settings.http_code, I18n.t("api.number_code") => Settings.error_number.not_type.to_s) end rescue_from APIError::Base do |e| case e when APIError::User::IdNotFound error!(Settings.validate_api_error_not_present.to_h, Settings.http_code, I18n.t("api.number_code") => Settings.error_number.not_present.to_s) when APIError::User::AccessHistoryFail error!(Settings.validate_api_error_not_date.to_h, Settings.http_code, I18n.t("api.number_code") => Settings.error_number.not_date.to_s) when APIError::User::DateFail error!(Settings.validate_api_error_not_tomorrow.to_h, Settings.http_code, I18n.t("api.number_code") => Settings.error_number.date_tomorrow.to_s) end end end end
Về cơ bản module này sẽ sử dụng Grape Exceptions để bắt và định nghĩa trả về mọi lỗi có thể có.
Như trong ví dụ trên có thể thấy:
- Grape Exceptions: APIError::Base
- 3 class lỗi là: APIError::User::IdNotFound, APIError::User::AccessHistoryFail và APIError::User::DateFail
Tương ứng với từng lỗi sẽ đẩy ra đầu nhận errors code và reason của nó.
4. Tạo ra module sau: app/api/v1/access_history.rb với nội dung
module Demo::V1::Users class AccessHistory < Grape::API include ::ValidationRescue resource :users_access_history do desc "update access history" params do requires :user_id, type: Integer requires :access_history, type: DateTime end post :update do raise APIError::User::AccessHistoryFail unless params[:access_history].is_a?(DateTime) date_history = params[:access_history] current_date = Time.zone.now raise APIError::User::DateFail unless current_date > date_history user = Demo::User.find_by_user_id params[:user_id] raise APIError::User::IdNotFound unless user.present? user.update_attribute :access_history, params[:access_history] end end end end
Đây là file chứa code xử lý chính của API. Trong đó khai báo rõ ràng:
- Params nhận vào gồm những gì và có bắt buộc hay không? requires :user_id, type: Integer
- Method sử dụng là gì? post :update
- Khi nào bắt ra lỗi và kiểu dữ liệu trả ra khi API chạy tới cùng.
KẾT LUẬN => Về cơ bản Ruby-Grape đã xây dựng một bộ khung chuyên nghiệp và cực kỹ dễ hiểu cho mọi API, việc phải làm bây giờ nếu có thêm một API chỉ cần sửa trên base này là xong.
=> Những thuộc tính khác mà ruby-grape cung cấp các bạn có thể tham khảo trên trang chủ ruby-grape
=> Để test được API có rất nhiều cách và công cụ hỗ trợ, lập trình viên thường sử dụng trực tiếp đường CURL trên console tuy nhiên có một công cụ khá hoàn hảo cho công việc này là POSTMAN các bạn có thể tìm hiểu tại đây