Tạo API đơn giản sử dụng Grape

Trong hướng dẫn này, chúng ta sẽ tìm hiểu về Grape, một REST-like API framework trong Ruby on Rails.

Giới thiệu project

Chúng ta sẽ sử dụng Rails và Grape với nhau để tạo ra API. Nó sẽ thực hiện các hoạt động CRUD back-end của model Employee cho các ứng dụng khác. Dưới đây là các API endpoints mà chúng ta sẽ tạo:

//Get all employee details
GET /emp_api       

//Add an employee
POST /emp_api/  {name:"Jay", address:"Kerala, India", age:"34"}             

//Delete an employee         
DELETE /emp_api/1

//Update an employee
PUT /emp_api/1

Bắt đầu

Hãy bắt đầu bằng cách tạo một ứng dụng Rails và cài đặt Grape gem. Tạo một dự án Rails mới

rails new emp_api

Thêm gem grape vào Gemfile và đừng quên chạy lệnh bundle.

gem 'grape'

Tạo 1 model Employee cho các hoạt động CRUD cơ bản.

rails g model EmpData name:string address:string age:integer
rake db:migrate

Tất cả các tệp API sẽ nằm bên trong thư mục app. Tạo một thư mục mới được gọi là api bên trong emp_api/app/. Bên trong thư mục emp_api/app/api/ tạo ra một thư mục khác gọi là employee, và một file nằm trong thư mục là data.rb. Tập tin này là nơi định nghĩa class để truy cập vào model Employee. Tiếp tục trong thư mục emp_api/app/api tạo ra 1 file là api.rb, nơi chúng ta sẽ gắng kết class được định nghĩa trong mp_api/app/api/employee/data.rb Thiết lập lại config/application.rb như dưới đây:

require File.expand_path('../boot', __FILE__)

require 'rails/all'

Bundler.require(*Rails.groups)

module EmpApi
  class Application < Rails::Application
    ## Newly Added code to set up the api code
    config.paths.add File.join('app', 'api'), glob: File.join('**', '*.rb')
    config.autoload_paths += Dir[Rails.root.join('app', 'api', '*')]
  end
end

Tạo API

Hãy bắt đầu bằng cách tạo API endpoint đầu tiên để lấy tất cả các chi tiết của nhân viên. Mở ứng dụng /api/employee/data.rb và tạo lớp module như sau:

module Employee
  class Data < Grape::API

    resource :employee_data do
      desc "List all Employee"
      get do
        EmpData.all
      end
    end
  end
end

Chúng ta cần truy cập vào function của class Employee::Data trong class API. Vì vậy, chúng ta sẽ sử dụng mount để làm cho class Employee::Data có thể truy cập được bên trong class API.

class API < Grape::API
  prefix 'api'
  version 'v1', using: :path
  mount Employee::Data
end

Mở tệp app/config/routes.rb và thêm đoạn code sau để định tuyến các cuộc gọi API đến root address của chúng ta.

Rails.application.routes.draw do
  mount API => '/'
end

Khởi động rails server, sau đó mở terminal và thử gọi:

curl http://localhost:3000/api/v1/employee_data.json

Bạn sẽ thấy response trả về 1 mảng trống vì chúng ta chưa có dữ liệu nào. Bây giờ chúng ta sẽ thử tạo 1 employee cũng bằng API. Mở app/api/employee/data.rb và thêm đoạn code sau đây để tạo API endpoint cho chức năng create employee.

desc "create a new employee"
## This takes care of parameter validation
params do
  requires :name, type: String
  requires :address, type:String
  requires :age, type:Integer
end
## This takes care of creating employee
post do
  EmpData.create!({
    name:params[:name],
    address:params[:address],
    age:params[:age]
  })
end

Restart server và sử dụng curl để gửi 1 POST request:

curl http://localhost:3000/api/v1/employee_data.json -d "name=jay;address=delhi;age=25"

Bây giờ, chúng ta đã có 1 employee:

curl http://localhost:3000/api/v1/employee_data.json

[{"id":1,"name":"jay","address":"delhi","age":25,"created_at":"2014-10-27T16:43:49.303Z","updated_at":"2014-10-27T16:43:49.303Z"}]

Tương tự, tạo API endpoint cho chức năng xóa nhân viên theo param ID:

# app/api/employee/data.rb

 desc "delete an employee"
 params do
   requires :id, type: String
 end
 delete ':id' do
   EmpData.find(params[:id]).destroy!
 end

Restart Rails server và test API xóa nhân viên chúng ta đã tạo trước đó:

curl -X DELETE http://localhost:3000/api/v1/employee_data/1.json

{"id":1,"name":"jay","address":"delhi","age":25,"created_at":"2014-10-27T16:43:49.303Z","updated_at":"2014-10-27T16:43:49.303Z"}

Bây giờ, nếu bạn kiểm tra danh sách employee, bạn sẽ thấy 1 mảng trống. Tiếp tục, để cập nhật chi tiết nhân viên, chúng ta cần truyền ID và các attributes được update. Thêm đoạn code sau để tạo API endpoint cho chức năng update địa chỉ của nhân viên.

# app/api/employee/data.rb

desc "update an employee address"
params do
  requires :id, type: String
  requires :address, type:String
end
put ':id' do
  EmpData.find(params[:id]).update({
    address:params[:address]
  })
end

Nhưng chúng ta không có nhân viên để cập nhật bởi vì ta đã xóa nó trước đó. Do đó, chúng ta sẽ cần phải thêm trở lại một nhân viên để cập nhật nó.

curl http://localhost:3000/api/v1/employee_data.json -d "name=roy;address=kerala;age=25"

{"id":2,"name":"roy","address":"kerala","age":25,"created_at":"2014-10-27T16:59:54.090Z","updated_at":"2014-10-27T16:59:54.090Z"}

Sau đó, sử dụng lệnh sau để cập nhật địa chỉ của nhân viên đó:

curl -X PUT http://localhost:3000/api/v1/employee_data/2.json -d "address=mumbai"

true

Tổng kết

Trong hướng dẫn này, chúng ta đã bắt đầu tạo một API CRUD đơn giản sử dụng Grape framework. Tài liệu chi tiết về nó có trên trang GitHub.