12/08/2018, 16:24

Sử dụng GraphQL Api trong Rails

Graphql là một công nghệ mới tuyệt vời giúp chúng ta có thể lấy data một cách nhanh chóng và hàng loạt các yêu cầu. GraphQL được Facebook phát triển một vài năm trước đây như là một cách để giải quyết một số vấn đề mà các API RESTful khác thường mắc phải. Một trong số đó là vấn đề lấy dữ liệu quá ...

Graphql là một công nghệ mới tuyệt vời giúp chúng ta có thể lấy data một cách nhanh chóng và hàng loạt các yêu cầu. GraphQL được Facebook phát triển một vài năm trước đây như là một cách để giải quyết một số vấn đề mà các API RESTful khác thường mắc phải. Một trong số đó là vấn đề lấy dữ liệu quá tải.

Quá tải là khi chung ta phải thực hiện nhiều vòng truy vấn đến máy chủ để đáp ứng nhu cầu dữ liệu mà chúng ta cần. Ví dụ: yêu cầu đầu tiên là lấy sách và yêu cầu tiếp theo là lấy các bài đánh giá cho cuốn sách đó. Hai truy vấn là tốn kém, đặc biệt là khi được thực hiện với thiết bị di động trên mạng lưới yếu. Hoặc là khi chúng ta cần dữ liệu cu thể như tên, email của người dùng nhưng do API không biết khi nào chúng ta cần, nó sẽ gửi cho chúng ta thông tin bổ sung không cần thiết, chẳng hạn như địa chỉ, ảnh, số điện thoại ....

Với GraphQL, chúng ta sẽ mô tả cho máy chủ chính xác những gì chúng ta đang tìm kiếm, không hơn, không kém. Một request điển hình có thể trông như thế này, yêu cầu một số thông tin về tài sản cho thuê cùng với tên của chủ sở hữu:

query {
  rentals {
    id
    beds
    owner {
      name
    }
  }
}

Response trả về sẽ có định dạng chính xác như request

{
  "data": {
    "rentals": [
      {
        "id": "203",
        "beds": 2,
        "owner": {
          "name": "Test A"
        }
      },
      {
        "id": "202",
        "beds": 1,
        "owner": {
          "name": "Test B"
        }
      }
    ]
  }
}

Với rail, chúng ta khai bảo một project mới

rails new blog-api --api

Thêm gem graphql vào trong Gemfile

gem 'graphql'
gem 'graphql-api'

và tạo các model sẽ sử dụng

rails g model Author name:string
rails g model Blog title:string content:text author:references
rails db:migrate

Mối quan hệ giữa các model sẽ như sau

class Author
  has_many :blogs
end

vậy là chúng ta có các bảng dữ liệu cơ bản cho backend, giờ chúng ta sẽ tạo controller để truy vấn cơ bản đên server bằng Graphql .

class GraphqlController < ApplicationController
  SCHEMA = GraphQL::Api::Schema.new.schema

  def create
    render json: SCHEMA.execute(
      params[:query], 
      variables: params[:variables] || {},
    )
  end

end

và thêm đường dẫn đến controller trong config/routes.rb

resources :graphql, only: :create

Bây giờ chúng ta hãy khởi động server và sử dụng curl để test với API theo các cấu trúc sau nếu như chúng ta đã có sẵn vài blog

curl -XPOST -d 'query=query { blogs { id } }' 
     localhost:3000/graphql

{"data":{"blogs":[]}}

và tạo một tác giả

curl -XPOST 
  -d 'query=mutation { 
         createAuthor(input: {name: "test A"}) { 
            author { id } 
     }}' localhost:3000/graphql

{"data":{"createAuthor":{"author":{"id":1}}}}

tạo một blog với Id tác giả vừa được trả về

curl -XPOST 
  -d 'query=mutation { 
         createBlog(input: {title: "foobar", author_id: 1}) { 
             blog { id } 
      }}' localhost:3000/graphql

{"data":{"createBlog":{"blog":{"id":1}}}}

Giờ chúng ta sẽ chạy lại câu truy vấn đầu tiên, lần nàychúng ta hãy thử và trả lại các tác giả blog cũng như tên blog.

curl -XPOST -d 'query=query { 
        blogs { 
          id
          title
          content
          author {
            name
          }
        }
     }' localhost:3000/graphql

và kết quả trả về sẽ là

{
  "data": {
    "blog": [
      {
        "id": "1",
        "title": "foobar",
        "content": "",
        "author": {
          "name": "test A"
        }
      }
    ]
  }
}
0