Bài viết này sẽ chia sẻ khái niệm và giới thiệu về GraphQL dành cho các bạn mới, chưa bao giờ nghe hoặc đã từng nghe qua cái tên GraphQL nhưng chưa biết chút gì về nó. Vậy GraphQL là gì? Dưới đây chúng ta sẽ cùng tìm hiểu.
Khái niệm và giới thiệu chung
- GraphQL là viết tắt của Graph Query Language do Facebook tạo ra từ năm 2012 cung cấp giao thức chung cho phép giao tiếp giữa client và server để cập nhật và lấy dữ liệu.
- Chúng ta có thể hiểu đơn giản chính là cú pháp mô tả cách yêu cầu lấy dữ liệu, và thường được dùng để load data từ một server cho client.
GraphQL được phát triển dựa vào các yếu tố chính sau:
Query
- Các yêu cầu do bạn đặt ra cho GraphQL được gọi là Query và Query này được phép support cho các nested fields trong tất cả hệ thống của ứng dụng.
- Vì vậy, khi client đã đưa ra yêu cầu và tạo query thì không cần lo lắng việc data lấy từ những source nào. GraphQL server sẽ đảm nhiệm và thực hiện toàn bộ mọi thứ.
Schema
- GraphQL sử dụng Schema như là một bản hợp đồng “quy chuẩn ngôn ngữ” giữa client và server, client có thể dùng những định nghĩa trong Schema để gửi lên server lấy dữ liệu từ server và server cũng dựa vào đó để có thể biết mình làm gì và trả về kết quả gì cho client.
- GraphQL có một ngôn ngữ riêng để định nghĩa Schema. Đó là Schema Definition Language (SDL) Mutations
Mutation
- Bên cạnh việc request data từ server, đôi khi phía Client cũng cần phải thực hiện một vài thay đổi tới data được lưu ở phía backend. Với GraphQL, ta có thể sử dụng mutations để làm điều đó. Nói chung, có 3 loại mutations thường gặp:
+ Tạo mới (create new).
+ Cập nhật (update).
+ Xóa (delete).
- Mutations tuân theo cấu trúc cú pháp giống như query, tuy nhiên nó luôn luôn phải bắt đầu với keyword mutation. (VD: create book, update book, delete book,…..).
Đọc qua những chi tiết trên, chắc hẳn chúng ta sẽ thấy GraphQL có nhiều điểm tương tự REST API đang hiện hành, vậy nó có ưu điểm gì vượt trội hay không? Tiếp sau đây chúng ta sẽ thực hiện so sánh.
So sánh với REST
Endpoint:
Với REST API, bạn sẽ lấy data bằng việc sử dụngnhiều endpoint.
- Với kịch bản trên, bạn sẽ sử dụng 1 endpoint /users/<id> để lấy dữ liệu của user.
- Sau đó bạn sẽ sử dụng 1 endpoint nữa là /user/<id>/posts để lấy tất cả các bài post của user.
- Endpoint thứ ba sẽ là /user/<id>/followers trả về danh sách các follower của user.

- Với GraphQL, bạn chỉ cần đơn giản gửi một câu query tới GraphQL Server bao gồm các yêu cầu dữ liệu cụ thể. Server sẽ trả về một JSON object đáp ứng các yêu cầu client gửi lên. Chú ý rằng Cấu trúc response mà Server trả về sẽ tuân theo chính xác cấu trúc lồng nhau mà được chỉ định trong query gửi lên từ Client.

Giải quyết Overfetching và Underfetching (thừa và thiếu):
REST:
- Client sử dụng endpoint để lấy dữ liệu về, và các endpoint trả về cấu trúc dữ liệu cố định.
- Điều này dẫn đến những khó khăn cho việc thiết kế API làm thế nào để có thể cung cấp cho client chính xác những gì mà client cần.
Overfetching: Client chỉ cần get về tên của các User nhưng với REST API, bạn gọi endpoint/user và nhận về mảng JSON dữ liệu của các user (có thể bao gồm luôn cả ngày sinh, email, địa chỉ,…)
Underfetching: Một endpoint cụ thể không cung cấp đủ thông tin yêu cầu cho client. Client phải thực hiện thêm những request khác để lấy thêm dữ liệu cần (lấy về 1 list phần tử, mỗi phần tử lại cần tạo một request để lấy dữ liệu yêu cầu).
GraphQL:
- Sử dụng 1 endpoint duy nhất, cho phép client chỉ định trực tiếp những dữ liệu họ cần, server trả về đúng dữ liệu theo cấu trúc lồng nhau được chỉ định trong query của client.
- Trực tiếp giải quyết xong Overfetching và Underfetching.
Database có mức độ dữ liệu càng lớn thì chúng ta càng thấy rõ độ linh hoạt và ưu điểm của GraphQL.
Đáp ứng sự thay đổi nhanh chóng phía Client.
REST API:
- Mỗi sự thay đổi phía giao diện người dùng (chẳng hạn như yêu cầu nhiều dữ liệu hơn), thì phía backend (server) cũng phải thay đổi để đáp ứng yêu cầu dữ liệu mới. Nó sẽ làm giảm hiệu suất, và chậm việc update product liên tục.
GraphQL:
- Có sự linh hoạt phía GraphQL, sự thay đổi phía Client sẽ không dẫn đến phải thay đổi phía server, bởi client có thể chỉ định chính xác yêu cầu dữ liệu mà client cần, do đó chỉ việc thay đổi phía Client.
Phân tích sự dư thừa dữ liệu.
REST API:
- Toàn bộ dữ liệu được trả về trong một API endpoint, như vậy chúng ta sẽ không biết được thông tin về việc sử dụng các trường dữ liệu cụ thể.
GraphQL:
- Chúng ta sẽ chỉ định chính xác những gì chúng ta cần, như vậy chúng ta sẽ biết được trường dữ liệu nào đang được sử dụng và trường dữ liệu nào không được request từ Client nữa.
Một vài nhược điểm của GraphQL:
- GraphQL luôn trả về HTTP status code là 200, bất kể query có success hay không. Nếu query lỗi, JSON response trả về sẽ có key errors, với các error message và stacktrace. Điều này gây khó khăn hơn trong việc error handling.

Độ phức tạp:
- GraphQL phải thiết kế schema trước, sẽ vất vả và tốn thêm thời gian, tuy nhiên sau này schema sẽ giúp bạn tránh nhiều lỗi và dễ dàng nâng cấp hơn.
- Khi Client không cần quan tâm đến data lấy từ đâu thì sự phức tạp được đẩy về phía server, GraphQL không phải là giải pháp tốt cho các ứng dụng đơn giản.
Vấn đề caching:
REST API:
- Sử dụng nhiều endpoint nên nó tận dụng HTTP caching để tránh việc phải tìm nạp lại tài nguyên.
GraphQL:
- Sử dụng 1 endpoint thay vì theo cơ chế caching của HTTP. Lưu vào bộ nhớ đệm là rất quan trọng vì nó làm giảm sự truy cập vào máy chủ. Khi sử dụng GraphQL, bạn phải sử dụng thư viện khác phía Client để đáp ứng việc caching.
Demo một project sử dụng GraphQL đơn giản với spring boot và mariaDB:
1. Tạo project Springboot, dùng maven:

2. Kết nối DB:

3. Tạo các model:


4. Thiết kế các schema cần thiết bằng file .graphql


5. Class service:


6. Resolver tương ứng:

