Build a to do list with Graphql in rails 5(Part 3)
Bài đăng này đã không được cập nhật trong 5 năm
Xin chào mn, tiếp tục với series tìm hiểu về graphql trong rails. Hôm trước mình đã giới thiệu các bạn về Schema và Types, hôm nay mình tiếp tục tìm hiểu phần quan trọng của Graphql đó là Queries và Mutations.
Queries
Nếu bạn đã quen thuộc với với REST, về cơ bản một method get dùng để fetch dữ liệu từ kho dữ liệu. Bạn có thể nghĩ Queries
tương tự như GET
nhưng nó có một số tính năng khác sau:
- Trong REST, khi chúng ta request với endpoint
/users
, có nghĩa là trả về danh sách các bản ghiuser
với mỗi record là toàn bộ cácfield
của nó(User.all
). Còn trong GraphQL bạn có thể chỉ trả về first_name, last_name hoặc bất cứ field nào bạn muốn. - Trong REST, để query một record bạn sử dụng
POST
nhưng trong GraphQL mọi request đều gửi dưới dạngPOST
và sử dụng chung endpoint chỉ tùy thuộc vào nó là mộtQueries
hay làMutations
như là một phần của request.
Dưới đây là một ví dụ về một Querie từ phía Client:
query {
users {
first_name
last_name
email
}
}
Giả định chúng ta có table users
, và chỉ return first_name
, last_name
và email
, chúng ta không cần quan tâm đến có bao nhiêu field tồn tại trong table users
.
Quay trở lại áp dụng cho ứng dụng của chúng ta nào!
Trong folder graphql/types
chúng ta mở file query_type.rb
.
Bây giờ chúng ta định nghĩa một query trả về danh sách các TodoList:
module Types
class QueryType < Types::BaseObject
field :all_todo_lists, [TodoListType], null: false
def all_todo_lists
TodoList.all
end
end
end
- Mỗi query được đặt như một field trong root query
- Tên của query sẽ tự động
camelcased
, vd:all_todo_lists
- >allTodoLists
- Method trong query accepts tham số như
object
,context
Chúng ta thử với Playground
, mở trình duyệt và truy cập http://localhost:3000/graphiql chúng ta sẽ thấy giao diện thế này:
Bạn có thể click vào Docs
để xem schema của query
mà mình đã định nghĩa.
Hãy thử nó xem nào, bạn nhìn thấy box phía bên trái màn hình màu trắng ko, đó là nơi để mình định nghĩa query. Bây giờ thử viết câu query để lấy danh sách các TodoList
và sau đó nhấn nút Play
để execute câu query, kết quả bạn thu được sẽ như sau:
Bạn có thể test với nhìu fields của todolist
Vậy Query với argument thì sẽ thế nào?
Chúng ta mở file query_type.rb
:
module Types
class QueryType < Types::BaseObject
field :todo_list, TodoListType, null: true do
description "Find a todo_list with id"
argument :id, ID, required: true
end
def todo_list(id:)
TodoList.find id
end
end
end
Kết quả test ở Playground
:
Mutations
Khi chúng ta muốn tạo, sửa hoặc xóa các bản ghi thì chúng ta làm với mutations
.
Dưới đây là cú pháp chung của một mutation
field :create_something, Types::SomeType do
argument :title, !types.String
argument :description, types.String
resolve ->(obj, args, ctx) do
SomeThing.create(
title: args[:title],
description: args[:description]
)
end
end
Trước tiên chúng ta tạo file test cho mutation cần viết:, bạn tạo mới file spec/grahpql/mutations/create_todo_list_spec.rb
require "rails_helper"
RSpec.describe Mutations::CreateTodoList do
let(:args) do
{
title: "Do my homework"
}
end
it 'increase todo list by 1' do
mutation = Mutations::CreateTodoList.new(object: nil, context: {}).resolve(args)
expect(mutation.id).to eq TodoList.last.id
expect(mutation.id).to eq TodoList.last.id
expect(TodoList.count).to eq 1
end
end
Chạy test với lệnh sau rspec spec/graphql/mutations/create_todo_list.rb
và hiển nhiên kết quả sẽ là failed. Bắt tay vào implemnent mutation nào!
Chúng ta sẽ tạo một TodoList
với mutations.
Trước hết ta tạo file base cho mutation
tương tự như file base_object
của query
. Bạn tạo file với tên mutations/base_mutation.rb
và chỉnh sửa nó một chút.
# mutations/base_mutation.rb
module Mutations
class BaseMutation < GraphQL::Schema::Mutation
null false
end
end
Và bây giờ chúng ta định nghĩa class CreateTodoList
kế thừa class BaseMutation
trong file mutations/create_todo_list.rb
để tạo mới một TodoList
:
# mutations/create_todo_list.rb
module Mutations
class CreateTodoList < BaseMutation
argument :title, String, required: true
type Types::TodoListType
def resolve(title: nil)
TodoList.create(
title: title
)
end
end
end
Bây giờ chúng ta expose
mutation
này vào app/graphql/types/mutation_type.rb
module Types
class MutationType < Types::BaseObject
field :create_todo_list, mutation: Mutations::CreateTodoList
end
end
Bây giờ chúng ta test trên Playground
:
Công đoạn cuối cùng là bạn chạy lại rspec xem nó có pass ko nhé!, kết quả thu được của mình:
Yeah! Vậy là chúng ta đã tìm hiểu sơ qua queries và mutations trong graphql!
Mình vừa học vừa tìm hiểu nên bài viết còn nhiều sai xót nên mình xin nhận cmt của mn để học hỏi thêm ạ! Cảm ơn mọi người đã đọc.
Happy coding!
Tài liệu tham khảo
All rights reserved