GraphQL như cơm bình dân
graphql
5
REST API
7
restful
14
White

ShinaBR2 viết ngày 29/11/2019

Lời nói đầu

Đây là một bài viết sinh ra trong lúc mình rảnh rỗi và cảm thấy quá lâu không viết một cái gì đó. Nội dung bài viết phù hợp cho những ai vẫn còn nghĩ mình chưa biết gì về GraphQL. Như thường lệ, mọi bài viết của mình đều có gắn tag và đảm bảo không trùng (ít nhất là trên kipalog) vì mình đã tìm kiếm trước khi bắt đầu viết.
Trước giờ mình không thích viết bài mà nó quá thiên về một công nghệ cụ thể nào đó, vì theo mình, công nghệ sẽ là thứ nhất thời, chỉ có kỹ năng của các bạn mới là cái mãi mãi. Mình thích cho người khác cái cần câu hơn là con cá, nên mình sẽ cố gắng hết sức làm được điều đó trong tất cả các bài viết, đây cũng không phải ngoại lệ.
Bài viết chủ yếu nói về hai cái chính: "Vì đâu sinh ra GraphQL" và "Thinking in GraphQL".

À đầu tiên, phải nói sơ qua GraphQL là gì? Thì mình cũng lên trang chủ copy về thôi chứ không tự biến mình thành thần thánh tự đề ra định nghĩa mới làm chi cho mệt.

GraphQL: A query language for your API

Query language, là một language, tất nhiên =)) cũng giống như một ngôn ngữ, bạn cần học syntax của nó và hiểu được nó dùng làm gì, tự khắc sẽ biết dùng như thế nào.

Vì đâu có GraphQL

Không chỉ riêng GraphQL, khi bạn đã là lập trình viên, hãy luôn tự hỏi mình tại sao mình rằng tại sao mình lại dùng ngôn ngữ/framework X. Trước GraphQL, REST (hay RESTful) đã làm rất tốt trong suốt một thời gian dài. Tất nhiên kẻ sinh sau đẻ muộn sẽ hơn đàn anh ở một điều gì đó, và quan trọng nhất là giải quyết một vấn đề nào đó mà người tiền nhiệm đã không làm được.

Mình lấy ví dụ một bài toán thực tế mà bất cứ lập trình viên nào cũng đã trải qua: lấy danh sách một sản phẩm, hiển thị cho người dùng, khi click vào một sản phẩm sẽ hiện chi tiết sản phẩm đó. Không có gì khó để chúng ta biết mình cần gì cả backend lẫn frontend. Mình sẽ lấy ví dụ model Product ở backend:

Product {
    id,
    name,
    dateCreated,
    //... some more fields
}

Đoạn code trên dùng ngôn ngữ gì mình cũng chẳng biết =)) mà chắc là ai cũng sẽ hiểu. Sau đó các bạn hình dung, bên frontend sẽ đại khái dùng vòng lặp, hiển thị lên giao diện, một cái table nào đấy những field trên.
Cơn ác mộng là ở đây, và cũng là điều khốn kiếp nhất mình từng trải qua trong suốt những năm làm dev. Chuyện gì sẽ xảy ra nếu một ngày đẹp trời API sẽ không trả về một hoặc vài field nào đấy trong cái model Product kia? Hoặc đơn giản là thay đổi field name thành label hay fucking_new_name gì đó?

Cách mình từng dùng để giải quyết vấn đề này (ở frontend), có 2 bước:

  1. Định nghĩa model riêng ở frontend, ví dụ như model ở trên
  2. Viết một hàm convert data trả về từ API thành model mình đã tạo ở bước 1

Xong, mình sẽ không phải tìm kiếm toàn bộ code trong frontend, trong toàn bộ table, vâng vâng và mây mây để đổi tên name thành fucking_new_name nữa. Thêm nữa, làm sao bạn có thể tìm kiếm chữ name trong toàn bộ project? Mỗi khi API có thay đổi, tất cả việc mình cần làm là sửa lại cái hàm convert mình đã viết ở bước hai ở trên mà vẫn chắc chắn được là không điều gì xảy ra cả.

Đây là một trong những câu chuyện mà GraphQL sinh ra để giải quyết. Nếu cần nói ngắn gọn về GraphQL thì chính là: bạn sẽ nhận đúng cái bạn cần, không nhiều hơn và cũng không ít hơn.
Tới đây là bạn đã biết GraphQL rồi đấy.

Thinking in GraphQL

Khoan hãy vào trang chủ hoặc search Google, tự mình suy nghĩ trước đã. Bạn "muốn nhận đúng cái bạn cần" thì nếu là mình sẽ phải làm gì. Thì ở đây mình sẽ phải làm những bước:

  1. Định nghĩa model, mọi thứ trong lập trình luôn nên xuất phát từ cái gọi là model.
  2. Nêu ra những data mình muốn lấy dựa vào model ở trên.
  3. Nhận được kết quả mong muốn.

GraphQL được sinh ra để làm giúp cho bạn những "dirty step" và bạn sẽ chỉ phải làm những việc trên (tất nhiên là theo một cú pháp được quy định sẵn). Một đặc điểm là bạn sẽ phải hiện thực GraphQL ở cả client lẫn server (frontend lẫn backend).
Quay lại với câu chuyện ở phần một, một backend developer dù có tâm đi chăng nữa, đáng tiếc là khi thay đổi một field thì API vẫn hoạt động bình thường. Đối với mình, đây là bug, không phải tính năng =)))) (nhưng đó giờ thế giới vẫn xem là tính năng).
Nhưng đối với GraphQL, API sẽ "phun" ra lỗi, và vô hình chung, GraphQL bắt buộc bạn phải làm theo đúng chuẩn, và câu chuyện khốn kiếp trên của REST sẽ không bao giờ xảy ra nữa. Bạn hãy suy nghĩ thử, làm cách nào để GraphQL biết được và phun ra lỗi đó. Nên nhớ hầu hết chúng ta sử dụng giao thức HTTP, là một giao thức không có trạng thái. Điều đó có nghĩa là server hoàn toàn không biết được request trước đó của client là gì.
Câu trả lời sẽ cho thấy được một ưu điểm, nhược điểm của GraphQL: bạn sẽ phải định nghĩa model ở cả client lẫn server. Chỉ cần một trong hai bên thay đổi data mình mong muốn mà không khớp với model của bên còn lại thì GraphQL sẽ quăng lỗi. Điều này sẽ giúp xác định lỗi thuộc về server/client một cách nhanh chóng mà trong khi đó sẽ mất thời gian hơn với REST.

Một điểm khác biệt cơ bản nhất giữa REST và GraphQL chính là "core concept". Trong khi REST sử dụng khái niệm "resource" làm core concept thì GraphQL sử dụng khái niệm là entity graph. Và có lẽ đây chính là lý do tại sao GraphQL lại có tên như vậy. Bạn có thể tìm hiểu sâu hơn bằng google hoặc một bài viết ở đây. Chính vì vậy mà ngày xưa khi chúng ta làm việc với REST, có rất nhiều URL tương ứng với từng resource, và các phương thức GET, POST, PUT... được sinh ra nhưng với GraphQL, chúng ta nên làm (và mặc định) mọi request (thường là HTTP request) chỉ tới 1 URL duy nhất. Mình đã từng thắc mắc liệu GraphQL có hỗ trợ các phương thức khác ngoài GET và POST nhưng sau đó mình thấy không còn cần thiết nữa. Đối với GraphQL, chỉ có 2 khái niệm là "Query" (lấy dữ liệu) và "Mutations" (làm gì đó thay đổi với dữ liệu).

Sau khi xong phần request, tới phần response. Làm việc với GraphQL là làm việc với JSON, syntax của GraphQL cũng xuất phát từ JSON. Ơn trời, điều này quá dễ cho lập trình viên chúng ta.

Tới đây thì thực sự mình cũng không biết phải viết gì thêm nữa. Như mình đã nói từ đầu, mình thích cho người khác cần câu hơn là con cá. Cách hiện thực graphQL thì cũng không phải quá phức tạp, các bạn cần làm ở cả client lẫn server, document chính thống tương ứng ở đây (code cho server) và ở đây (code cho client). Đừng bận tâm quá nhiều vào code, hãy hiểu vấn đề mình cần phải giải quyết.

Tóm gọn lại là những thứ cần nhớ về GraphQL:

  • Là một query language => language dùng để query (query là gì mình không biết, bạn tự google).
  • Định nghĩa model là việc làm đầu tiên nhớ tới khi làm việc với GraphQL ở cả client lẫn server.
  • GraphQL đã làm hết những "dirty thing" rồi, bạn chỉ cần nói "Ê, tôi cần lấy data x, y, z từ model A, B, C mà tôi đã định nghĩa trước đó".
  • Core concept của REST là "resource" còn của GraphQL là "entity graph".
  • Query là lấy dữ liệu, Mutations là làm gì đó thay đổi với dữ liệu.

Mình có một vài câu hỏi dành cho các bạn:

  • GraphQL có xài được cho ngôn ngữ/framework X?
  • Tại sao cần phải xài GraphQL?

Mục tiêu của bài viết là bạn đọc xong mà không hỏi hai câu hỏi trên là đạt yêu cầu. Cảm ơn các bạn đã dành thời gian cho một bài viết trong lúc rảnh rỗi của mình =))) mọi ý kiến đóng góp đều được mình đọc và phản hồi nếu như có sai sót (mà chắc là có rồi :)))))) )

ShinaBR2 29-11-2019

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

ShinaBR2

12 bài viết.
116 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
69 16
Đây là một vấn đề kinh điển, và có rất nhiều bài viết về nó, tuy nhiên đa phần là dịch từ bản gốc ra và sao chép lại một vài câu lệnh, và câu hỏi t...
ShinaBR2 viết hơn 2 năm trước
69 16
White
47 11
Vào một ngày đẹp trời, khi bạn nhận được yêu cầu phải thiết kế database cho một hệ thống, câu hỏi đầu tiên được đặt ra, quy trình làm ra nó sẽ cụ t...
ShinaBR2 viết hơn 2 năm trước
47 11
White
38 10
Bàn về code thối Hãy tự đặt câu hỏi cho bạn, khi bắt đầu lập trình, bạn nghĩ tới điều gì? Đi phỏng vấn Điều đầu tiên tôi muốn nói về những câu hỏ...
ShinaBR2 viết 2 năm trước
38 10
Bài viết liên quan
White
3 1
Chào các bạn Mình vừa mới làm một side project để cập nhật công nghệ mới nhất về React stack. Shopping Cart của mình được build bằng TypeScript, N...
Đinh Viễn viết 6 tháng trước
3 1
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
12 bài viết.
116 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!