12/08/2018, 15:26

Phân tích một JSON API với Rails

Đặt vấn đề Bạn đang làm việc trên một dự án Rails, trong đó có một yêu cầu là phải lấy data từ một domain X đã có sẵn JSON API. Vậy làm thế nào để lấy JSON từ API của domain X, xử lý kết quả và sử dụng ở dự án bạn đang thực hiện? Hướng giải quyết Để xử lý vấn đề nêu trên, Ruby Toolbox liệt kê ...

Đặt vấn đề

Bạn đang làm việc trên một dự án Rails, trong đó có một yêu cầu là phải lấy data từ một domain X đã có sẵn JSON API. Vậy làm thế nào để lấy JSON từ API của domain X, xử lý kết quả và sử dụng ở dự án bạn đang thực hiện?

Hướng giải quyết

Để xử lý vấn đề nêu trên, Ruby Toolbox liệt kê ra hơn 25 HTTP Clients. Các bạn có thể tìm hiểu để lựa chọn một gem thích hợp cho dự án của mình. Bài viết sau đây mình xin giới thiệu 3 cách từ cơ bản đến nâng cao để lấy JSON API và xử lý với Rails. Bài viết sẽ chỉ hướng dẫn các bạn các bước để xử lý kết quả JSON trả về, vì vậy sẽ bỏ qua các bước tạo demo rails app và chỉ đi vào 3 bước cụ thể như sau:

  • Định nghĩa URL
  • Gửi 1 HTTP Request
  • Xử lý kết quả JSON trả về

Cách 1: Sử dụng thư viện NET::HTTP

Đây là thư viện chuẩn của Ruby. Sử dụng nó sẽ không phải install bất cứ gem hỗ trợ nào. Tuy nhiên, 1 điều chắc chắn rằng, gem sinh ra là để hỗ trợ cho người lập trình. Chính vì thế, nếu không dùng gem thì chắc chắn rằng, người lập trình sẽ phải xử lý nhiều việc hơn khi chỉ require thư viện này. Ví dụ, từ 1 URL để get API JSON, thì trước tiên, ta phải tạo 1 đối tượng URI từ URL đó, rồi sử dụng phương thức get của để gửi request và lấy giá trị trở về. Tất nhiên nếu dùng gem những công việc đó sẽ chỉ gói gọn trong 1 dòng lệnh. Hãy thử dùng thư viện này với một request từ https://api.stackexchange.com/ Thực hiện 3 bước mình đã nêu trên sẽ có đoạn code như sau

// require thư viện
require "net/http"
require "json"

// Định nghĩa URL, chính xác là tạo một đối tượng URI từ URL đó
url = "https://api.stackexchange.com/2.2/tags?order=desc&sort=popular&inname=ruby&site=stackoverflow"
uri = URI(url)
// Gửi HTTP Request với method get
response = Net::HTTP.get(uri)
// Xử lý kết quả trả về, ở đây mình chỉ in ra đoạn JSON trả về
puts JSON.parse(response)

Ở đây mình tạo file api.rb để test chứ không để trong Rails app nên sau khi chạy ruby api.rb thì kết quả trên màn hình console sẽ trả về đống JSON như sau

Cách 2: Sử dụng gem HTTParty

Git repo Đây là 1 gem được xây dựng dựa trên thư viện NET::HTTP. Mọi việc sẽ trở nên đơn giản hơn khi dùng gem. Ví dụ như chỉ với lệnh HTTParty.get(url) thì đã làm được 2 việc là tạo 1 đối tượng URI cho URL và sử dụng phương thức get của NET::HTTP để gửi request và nhận response. Tất nhiên, để sử dụng được gem này bạn phải cài đặt nó trước

gem install httparty

Ví dụ:

require "httparty"

url = "https://api.stackexchange.com/2.2/tags?order=desc&sort=popular&inname=ruby&site=stackoverflow"
// 2 bước trong 1 câu lệnh
response = HTTParty.get(url)
// Trả về response
puts response.parsed_response

Và kết quả trả về vẫn như trên

Cách 3: Sử dụng gem faraday

Git repo Gem này dành cho những lập trình viên muốn kiểm soát luồng, chu kỳ request, response. Nó cũng cấp giao diện chung cho nhiều adapter như: NET::HTTP, EventMachine, HTTPClient, NET::HTTP::Persistant, Excon, Patron. Chính vì nó cung cấp giao diện chung cho nhiều adapter, trong đó NET::HTTP là adapter mặc định, nên khi bạn muốn gửi request và nhận response đơn giản thì cũng chỉ dùng 1 lệnh đơn giản mà không phải config gì thêm Faraday.get(URL). Tất nhiên, đã dùng gem Faraday thì phải đụng tới những config để điều khiển được chu kỳ của các request, response, và đàng sau đó là những cái vi diệu của gem mà phải đụng tay vào code mới thấy được. Ngoài việc cài đặt gem, bạn còn phải cài đặt 1 middleware đi kèm có nhiệm vụ là điều khiển các luồng của chu trình request, response

gem install faraday
gem install faraday_middleware

Ví dụ:

require "faraday"
require "faraday_middleware"

url = "https://api.stackexchange.com/2.2"

conn = Faraday.new(url: url) do |faraday|
  faraday.adapter Faraday.default_adapter // default_adapter = NET::HTTP
  faraday.response :json // Kiểu dữ liệu trả về
end
// Send request, method get và các params
response = conn.get("tags", order: "desc", sort: "popular", inname: "ruby", site: "stackoverflow")
// Kết quả trả về
puts response.body

Trong bài mình send request với các params giống nhau nên chắc chắn kết quả trả về sẽ không khác biệt gì với 2 cách trên

Kết luận

Trong bài viết mình đã hướng dẫn cách lấy 1 JSON API về cho một ứng dụng Rails tiếp tục xử lý, từ cách code chay là sử dụng thư viện, đến cách sử dụng gem đơn giản như HTTParty, và gem phức tạp hơn xí là Faraday. Ngoài ra còn có nhiều cách khác nữa, mỗi cách đều có những ưu và nhược điểm riêng của nó. Nếu các bạn có hứng thú mày mò về vấn đề này, có thể ghé thăm link này và ngâm cứu. Bài viết có tham khảo từ: https://www.twilio.com/blog/2015/10/4-ways-to-parse-a-json-api-with-ruby.html

0