Vì sao bạn nên (và không nên) chọn Graphql thay cho RestAPI

Vào một ngày đẹp trời, sếp quăng 1 dự án fullstack mới, bảo bạn triển khai.

Hàààà… bạn thở dài, nhắp ly cà phê…

“Frontend react hay vue, backend thì chắc chọn 1 trong mấy thằng nestjs, django, laravel… Cầu nối giữa 2 thằng này thì RestAPI. Xong, như mọi khi, nhàm nhưng khỏe. Giờ bắt tay vào việc thôi.”

Nhưng khoan, từ từ, bạn có muốn thử Graqhql thay cho thằng RestAPI không? Ấy, tôi thấy 2 hàng lông mày bạn xô lại, hẳn đang nghĩ đồ nào xài quen thì cứ dùng, mắc mớ gì đổi sang cái mới. Không sai, tuy nhiên, hãy bỏ chút thời gian đọc qua bài này, rồi đưa ra quyết định sau cũng đâu muộn ha!

I. Trước tiên, giới thiệu chút về Graphql

Phát triển bởi Facebook và công khai vào 2015, Graphql là ngôn ngữ truy vấn được sử dụng cho ứng dụng web và dịch vụ Api để lấy dữ liệu. Nói một cách ngắn gọn, Graphql có chức năng như RestAPI, nhưng có type, có thể định dạng cấu trúc dữ liệu trả về bằng Schema, cần gì Graphql sẽ trả lại cho bạn đúng chừng đó, không thiếu một cắc, không thừa một xu.

II.Top 3 lí do chính bạn nên dùng Graphql

Trước hết chúng ta sẽ nhìn qua cách lấy dữ liệu của Rest và Graphql.

Bài toán đặt ra: lấy dữ liệu về user hiện hành, các bài post và thông tin follower của user đó.

Quá trình lấy dữ liệu của RestAPI


Rest: do tính chất mỗi nguồn tài nguyên là 1 endpoint, chúng ta cần 3 chuyến đi và về để lấy được dữ liệu cần thiết.

Qúa trình lấy dữ liệu của Graphql


Graphql: tất cả mọi tài nguyên đều lấy qua 1 endpoint duy nhất, ta có thể lấy dữ liệu từ nhiều nguồn tài nguyên khác nhau.

Từ ví dụ trên hẳn bạn cũng có thể thấy rằng:

1. Graphql lấy được nhiều nguồn tài nguyên trong 1 request

Tùy vào schema được định nghĩa mà request của Graphql có thể lấy được nhiều nguồn tài nguyên, miễn rằng server có định nghĩa resolver để lấy các nguồn tài nguyên tương ứng. Ứng dụng sử dụng Graphql có thể chạy mượt dù kết nối chậm.

“Ví dụ cách lấy dữ liệu trên của Rest không thực tiễn, vì server có thể định nghĩa dữ liệu trả về kèm theo các dữ liệu liên quan, nên Rest hoàn toàn có thể chỉ tốn 1 request như Graphql.”

Ok ok, nhưng dù có vậy thì Graphql còn có 1 ưu điểm khác ngay sau đây:

2. Graphql phòng tránh được vấn đề lấy thừa/thiếu dữ liệu của Rest

Với giả thiết server phía Rest định nghĩa 1 hàm “toàn năng” lấy được dữ liệu nhiều tài nguyên trong 1 request.

Nếu vì 1 lí do nào đó bạn chỉ muốn lấy thông tin user thì sao, hoặc không lấy thông tin của followers?

Dùng endpoint cũ bạn có thể filter dữ liệu cần lấy ra, nhưng các dữ liệu bị lượt bỏ đi sẽ thừa (lấy thừa dữ liệu).

Mặt khác, trường hợp sau này yêu cầu thay đổi, client cần thêm thông tin comment của mỗi bài post thì với endpoint cũ, bạn sẽ không lấy được dữ liệu về comment, buộc bạn phải gọi thêm 1 request khác (lấy thiếu dữ liệu).

Một cách khác là chúng ta định nghĩa 1 hàm khác bên phía server để lấy dữ liệu cần thiết.
Thay đổi bên server tức là đội phát triển bên client phải ngồi đợi, cộng thêm chi phí thay đổi nữa.

Graphql thì sao? Server chỉ trả về các loại dữ liệu đúng với schema mô tả, không hơn không kém. Nếu muốn lấy thêm dữ liệu mới, hoặc lượt bỏ bớt dữ liệu, chúng ta chỉ cần sửa lại schema, không cần phải định nghĩa thêm một resolver khác phía server.

Ngoài ra, việc ngăn chặn tình trạng lấy thừa dữ liệu sẽ giúp chúng ta tiết kiệm được băng thông, giảm thiểu chi phí.

3. Lợi ích của schema và type

Bằng việc sử dụng schema để mô tả cấu trúc dữ liệu trả về, tự động chúng ta sẽ có 1 bản tài liệu chi tiết các dữ liệu có thể trả về từ phía server cũng như kiểu dữ liệu tương ứng của chúng, giúp đẩy nhanh tốc độ phát triển.

Với schema đóng vai trò hợp đồng giữa client và server, các đội dev ở bên có thể làm việc 1 cách trơn tru mà không cần phải liên lạc thường xuyên với nhau, bởi 2 bên đã thống nhất khuôn mẫu thông tin luân chuyển.

Với type, dev tránh được việc chuyển đổi kiểu dữ liệu một cách thủ công.

“Vậy có thể nói rằng Graphql ưu việt hơn Rest. Graphql sẽ làm lu mờ Rest giống như cái cách React dìm jquery?”

Câu trả lời là… còn tùy. Graphql không phải là chìa khóa vạn năng và trong một số tình huống, sử dụng Rest sẽ hợp lí hơn.

III. Một vài lí do khiến Graphql không lợi hại như bạn tưởng

1. Khi ứng dụng chỉ ở mức đơn giản

Khi ứng dụng không lớn và đơn giản, sử dụng Graphql sẽ làm ứng dụng trở nên phức tạp vì nào những schema, type, resolver, query, mutation…

2. Graphql không hỗ trợ upload ảnh lên server.

Graqhql tập trung vào việc truy vấn và thao tác dữ liệu hơn là xử lý upload file. Graphql không yêu cầu phải tuân theo một giao thức truyền tải cụ thể nào, ví dụ như HTTP vốn thường hay được sử dụng để upload file. Trái lại, Graphql sẽ để việc xử lý upload file cho các ứng dụng sử dụng nó.

Chúng ta có thể khắc phục bằng cách:
- Chuyển thành dữ liệu base64  -> khiến kích thước request phình lên đáng kể
- Sử dụng thư viện hỗ trợ upload ảnh cho Graphql
- Sử dụng RestAPI

3. Thông báo lỗi của Graphql không chi tiết bằng Rest

Khi gặp lỗi Graphql chỉ trả về thông báo lỗi. Bên Rest sẽ trả thêm status code giúp chúng ta biết cụ thể ngữ cảnh của lỗi, ví dụ lỗi không tìm thấy 404, lỗi máy chủ 500, lỗi xác thực 401…

Graphql có thể giải quyết bằng cách cài thư viện, và đó cũng là nhược điểm vì tăng kích thước cũng như độ phức tạp của ứng dụng.

4. Hiệu suất

Trớ trêu thay, điểm mạnh – tiết kiệm thời gian vì ít gọi request – lại có thể trở thành điểm yếu nếu không cẩn thận. Việc lấy được nhiều nguồn tài nguyên khác nhau có thể khiến cho schema to ra và nếu cứ thêm trường một cách vô tội vạ, một vài request với schema khủng bố có thể sẽ khiến server sập.

Giải pháp cho vấn đề trên có thể kể đến dataloader, giới hạn độ sâu query.

5. Graphql làm được gì, thì Rest cũng có thể làm được vậy

Tất nhiên là phải nhờ vào thư viện ngoài. Với các tool như json schema, Odata bạn có thể có được các lợi ích của Graphql trên Rest. Tuy vậy, như đã đề cập ở trên, việc cài thêm thư viện sẽ khiến cho ứng dụng to lên và tăng độ phức tạp. Tùy vào hoàn cảnh thực tế, chọn Graphql sẽ khỏe hơn vì nó đã hỗ trợ sẵn.

IV. Kết luận

Tùy thuộc vào dự án thực tế, bạn nên xem xét để chọn Rest hay Graphql. Nếu dự án nhỏ, đơn giản và không quá quan trọng hiệu suất thì hãy chọn Rest. Ngược lại, Graphql sẽ là 1 lựa chọn tuyệt vời.

Nếu bạn chưa thử qua Graphql thì hãy thử ngay từ bây giờ, tạo một làn gió mới trong trải nghiệm viết code.

V. Nguồn tham khảo

  1. Đặc trưng của Graphql
  2. Tìm hiểu sâu về Graphql
  3. Lí do không nên dùng Graphql