Giải ngố API – Phần 4: Ngắn gọn thì GraphQL hoạt động kiểu gì?

Kết thúc nội dung Giải ngố API – Phần 3: API Authentication và các thể loại API data formats, kỳ này tôi sẽ chuyển sang một đối tượng hay ho đã đề cập trước đó là GraphQL. Ở nội dung này, tôi sẽ tập trung vào 2 vấn đề cơ bản (và quan trọng) là lý do ra đời, và nguyên lý hoạt động của GraphQL. Các vấn đề chi tiết hơn tôi sẽ sắp xếp để lần lượt giới thiệu sau.

#1. Mấy ông đẻ ra thêm GraphQL để làm gì khi đã có REST API?

Đầu tiên, cần xác định nhanh là người ta không đẻ ra thêm GraphQL API vì rảnh quá không có gì làm. Về cơ bản, GraphQL ra đời là để giải quyết một số vấn đề còn tồn đọng của REST API như tôi đã có đề cập trong Giải ngố API – Phần 2: Web APIs hoạt động ra sao?,

“…

GraphQL cải tiến hơn so với REST APIs trong các vấn đề:

  • Có thể chỉ cần sử dụng 1 request để lấy đúng chính xác các dữ liệu cần thiết vốn có thể phải chạy bằng nhiều REST API request;
  • Có thể sử dụng HTTP nhưng chỉ cần một entry point URL với POST method;
  • Có thể sử dụng CRUD với POST request dựa vào 3 operationquery, mutationsubscription.

…”

Cụ thể, GraphQL sử dụng Schema stitching để gom cả đám GraphQL services vô một GraphQL schema dạng unified gateway (kiểu như “một cửa một dấu”). Lúc này, client muốn gì thì cũng chỉ cần ghé vô cái “cửa” này và trình bày nhu cầu (theo cú pháp quy định trong schema) để nhận kết quả.

Ngoài ra, với các ứng dụng phức tạp, một kỹ thuật cao cấp hơn là Schema federation sẽ được sử dụng. Với Schema federation, các service sẽ được nghiên cứu thiết kế với khả năng kết nối với các service khác từ đó bảo đảm đám schema con tương ứng có thể được tích hợp tự động để tạo thành schema “trùm cuối”.

#2. Vậy rồi GraphQL hoạt động kiểu gì?

Để minh hoạ cách thức hoạt động của GraphQL, tôi sẽ tạm lấy ý tưởng về cách thức mần ăn một nhà hàng có tên gọi GraphQL trong các phần tiếp sau đây.

GraphQL restaurant
GraphQL restaurant

Nguồn: DALL·E

#2.1 Schema – Menu để gọi món

Khi bàn tới nhà hàng, thứ đầu tiên cần được nhắc đến chắc chắn phải là menu để gọi món. Và với nhà hàng GraphQL, chủ quán quyết định sáng tác ra một cái tên mới cho menu là Schema.

Một lần nữa, tôi cũng đã có đề cập sơ bộ về Schema trong Giải ngố API – Phần 2: Web APIs hoạt động ra sao?,

“…

Về cơ bản, GraphQL cũng là RESTful (tức là tuân thủ 6 constrains – ràng buộc của REST API trình bày ở trên) nhưng được thiết kế với định hướng thiên về kiểu query (truy vấn) – nghĩa là đối tượng này được cấu trúc để hoạt động theo kiểu DB query language ví dụ như SQL. Cụ thể:

  • GraphQL sử dụng schemas – collections of data (đại khái là bộ dữ liệu);
  • GraphQL lưu trữ tài nguyên vào graph data structures (cấu trúc dữ liệu dạng graph).

…”

Như vậy, có thể hiểu đơn giản Schema giống như “thực đơn” chứa đựng các thông tin để cho GraphQL client (khách) biết GraphQL server (chủ quán) đang “phục vụ” những thể loại thông tin (món ăn) gì. Xem xét về mặt cấu trúc cơ bản:

  • GraphQL schema sẽ bao gồm thông tin về thành phần cơ bản nhất là Object types – đại khái là các kiểu đối tượng có thể hốt về từ GraphQL service;
  • Object types sẽ có các fields – là các thuộc tính nhất định của Object.

Trong ví dụ “trích đoạn” của Schema bên dưới, Object typesCharacter sẽ có 2 field tương ứng là nameappersIn (cái đám thông tin lằng ngoằng đằng sau field tôi sẽ giới thiệu sau).

Schema example
Schema example

Nguồn: Schemas and Types | GraphQL

Đồng thời, GraphQL cho phép hình thành liên kết giữa các Object do vậy schema sẽ có thể thể hiện ở dạng graph bao gồm:

  • Nodes: Tương ứng với các Objects;
  • Edges: Tương ứng với cách tạo liên kết giữa các Nodes (cụ thể hơn là đám field của một object sẽ tham chiếu đến một Object khác).

Bạn có thể xem graph minh họa bên dưới (GraphQL Voyager (graphql-kit.com)) hoặc nghiên cứu chi tiết hơn với thông tin trong graphql-kit/graphql-voyager: 🛰️ Represent any GraphQL API as an interactive graph (github.com).

GraphQL graph demo
GraphQL graph demo

Lưu ý: Hình trên chỉ để giúp bạn có cái nhìn sơ bộ về dung nhan của cái graph. Tôi sẽ lần lượt giới thiệu các thứ liên quan sau nên nếu giờ bạn nhìn qua cái graph trên mà không hiểu thì cũng không có vấn đề gì.

Quay trở lại với cái nhà hàng GraphQL, đến đoạn này khách đã cầm được cái menu trên tay để ráo riết nghiên cứu và chuẩn bị gọi món.

#2.2 Query – Gọi món như nào để phục vụ bàn có thể hiểu?

Sau một hồi ngâm cứu cái menu, khách đã chọn được món ưng ý và bắt đầu vẫy tay để tương tác với phục vụ bàn. Vấn đề là khách đang ngồi ở nhà hàng GraphQL, và quy định của nhà hàng là khách phải gọi bằng ngôn ngữ GraphQL thì phục vụ bàn mới hiểu.

Về cơ bản, GraphQLquery language dùng để để tương tác và trích xuất thông tin từ server nên khái niệm query của GraphQL cũng tương đồng với khái niệm query khi làm việc với các Database. Tuy nhiên, cái Syntax (cú pháp) của GraphQL query để tương tác sẽ có nhiều điểm khác biệt. Ví dụ, mỗi GraphQL query sẽ bắt đầu với định nghĩa về operation’s root type (đại khái là kiểu tương tác) có thể thuộc 1 trong 3 loại là Query, MutationsSubscritption (Tôi sẽ giới thiệu kỹ hơn về đám này trong phần tiếp theo.)

Lưu ý: Chỗ này hơi dễ nhầm lẫn giữa chữ query (truy vấn nói chung) và chữ Query (một trong 3 loại operation’s root type). Từ đoạn này tôi sẽ dùng Query (viết hoa chữ Q) khi muốn đề cập đến cái operation’s root type.

Và như đã đề cập ở phần Schema nói trên, trước khi có thể sử dụng, đám operation’s root type này phải được định nghĩa trong schema với các field tương ứng. Ví dụ tôi có thể soạn cái schema với các nội dung như sau.

type User {

       id: ID

       username: String

       email: String

}

 

type Query {

       users: [User]

}

 

schema {

       query: Query

}

Với schema định nghĩa trên, tôi sẽ có thể gửi cái query đến GraphQL server đã triển khai cái schema nói trên để hốt về thông tin usernameemail của object User.

query {

       users {

             username

             email

}

}

Tôi quay trở lại với ông khách đang ngồi ở cái nhà hàng GraphQL. Nhờ ông bà độ, khách có thể đọc qua một lần và hiểu ngay các quy tắc lằng nhằng nói trên. Do vậy, khách có thể tự tin để dõng dạc gọi món cho phục vụ bàn ghi nhận lại.

#2.3 Query parser – Công cụ để đầu bếp phân tích yêu cầu gọi món nhận từ phục vụ bàn

Tiếp tục diễn biến với nhà hàng GraphQL, lúc này khách đã hoàn thành công tác gọi món. Do vậy, phục vụ nhanh chân mang cái ghi chú món ăn vào cho đầu bếp nghiên cứu và phân tích với một công cụ có tên gọi là query parser.

Đúng như tên gọi, query parser dùng để parse (đại khái là phân tích) cái query ra để diễn giải cho GraphQL server biết client đang muốn mần cái gì.

Cụ thể, query parse sẽ đọc và trích thông tin từ các queries bằng cách:

  • Chuyển đổi query string thành Abstract Syntax Tree – AST (một dạng hierarchical object – đối tượng có phân cấp để thể hiện query bao gồm field, argument và các thông tin khác;
  • Xác minh AST dựa trên schema để bảo đảm chỉ chấp nhận các query đúng chuẩn đã quy định.

Đến đoạn này thì đầu bếp nhà hàng GraphQL đã kiểm tra và xác nhận rõ rõ khách muốn gọi món gì. Công việc tiếp là chuẩn bị nồi niêu xoong chảo và tôm cua cá mực để bắt đầu chế biến.

#2.4 Resolver functions – Công cụ để đầu bếp chế biến và lên món cho khách

Để triển công tác chế biến món ăn chuẩn mực theo yêu cầu của khách, đầu bếp nhà hàng GraphQL sẽ phải móc ra tiếp cái tool hỗ trợ thứ 2 là resolver functions.

Ông resolver functions sẽ chịu trách nhiệm cho việc sáng tác ra response dựa trên dữ liệu từ các field được chỉ định trong client query. Để làm được việc này, resolver functions có thể sẽ phải thực hiện 1 hoặc tất cả các thứ sau đây:

  • Kết nối đến external DB ví dụ như MySQL và truy vấn các thông tin liên quan;
  • Đọc dữ liệu từ filesystem nội bộ;
  • Tạo HTTP request đến các hệ thống khác với REST API.

Đến đây coi như đầu bếp nhà hàng GraphQL đã hoàn thành trách nhiệm. Giờ ông phục vụ chỉ cần lượn vào hốt hàng lên cho khách là kết thúc quy trình (bảo đảm lên đúng món, còn ngon hay dở thì hên xui!).

#2.5 GraphQL client libs – Công cụ cải thiện trải nghiệm khách hàng

Như bạn có thể thấy, dù quá trình khách gọi món ở nhà hàng GraphQL đã thành công tốt đẹp. Tuy nhiên, việc nghiên cứu menu (Schemamục 2.1) và quy tắc gọi món (Querymục 2.2) có khi đòi hỏi khách phải nỗ lực vã mồ hôi mới có đúng món để bỏ vào mồm. Để giải quyết vấn đề này, khách có thể nhờ vào sự trợ giúp của một đối tượng có tên gọi là GraphQL client libs.

Tất nhiên, tương tự như RESTful API, trước khi client có thể tương tác, các đại ca triển khai GraphQL server cũng sẽ phải thiết lập GraphQL API và cung cấp thông tin cho client. Và lúc này, để tương tác với GraphQL API, client có thể sử dụng các GraphQL client libs ví dụ như Apollo (Introduction to Apollo Client – Apollo GraphQL Docs) hay urlq (Overview | urql Documentation (formidable.com)).

GraphQL client libs
GraphQL client libs

Lưu ý:

  • Bạn có thể bơi vào trang GraphQL Code Libraries, Tools and Services để xem thêm các phương án khác, nếu cần;
  • Ngoài các phương án chuẩn nói trên, nếu cần thử nghiệm nhanh kiểu mì ăn liền, bạn cũng có thể xem xét các phương án sử dụng command line (ví dụ như cURL).

Với GraphQL client libs, việc tương tác với GraphQL API nói chung và các công tác nâng cao như xử lý caching để tối ưu hiệu quả, tích hợp vào front-end framework (ví dụ như React), xử lý lỗi sẽ trở nên nhẹ nhàng.

Như vậy, với mảnh ghép cuối cùng là GraphQL client libs, giờ khách đã có thể ngồi rung đùi tận tưởng các bữa ăn xa hoa ở nhà hàng GraphQL mà còn phải lo lắng quá nhiều vấn đề nghiên cứu thực đơn và gọi món.

Đến đây tôi cũng xin tạm dừng phần giới thiệu đầu tiên về GraphQL. Từ các phần sau, tôi sẽ bắt đầu đi vào các nội dung chi tiết hơn của GraphQL.

Leave a Reply

Your email address will not be published. Required fields are marked *