

GraphQL là một ngôn ngữ truy vấn API được phát triển bởi Facebook vào năm 2012 và được công bố mã nguồn mở vào năm 2015. Trong thời đại mà các ứng dụng web và di động đòi hỏi dữ liệu ngày càng phức tạp, GraphQL giải quyết vấn đề cốt lõi của việc truy xuất dữ liệu: làm thế nào để lấy chính xác những gì bạn cần mà không thừa hay thiếu. Bài viết này sẽ phân tích chi tiết GraphQL là gì, so sánh với REST, và cách bạn có thể áp dụng nó vào dự án của mình.
GraphQL và REST – Khác biệt cốt lõi
REST (Representational State Transfer) là kiến trúc API phổ biến nhất hiện nay, trong đó mỗi tài nguyên được xác định bởi một URL endpoint riêng biệt. Ví dụ, để lấy thông tin một cuốn sách và tác giả của nó, bạn có thể phải gọi hai endpoint khác nhau: /books/1 và /authors/5. Điều này dẫn đến vấn đề “over-fetching” (lấy quá nhiều dữ liệu) hoặc “under-fetching” (lấy quá ít, phải gọi nhiều lần).
GraphQL giải quyết triệt để vấn đề này. Thay vì nhiều endpoint, GraphQL sử dụng một endpoint duy nhất. Client gửi một truy vấn (query) chỉ rõ chính xác những trường dữ liệu cần lấy. Như Apollo GraphQL đã phân tích, trong REST, hình dạng tài nguyên được xác định bởi server, còn trong GraphQL, client tự quyết định cần gì tại thời điểm đó. Điểm khác biệt quan trọng khác là trong REST, endpoint chính là danh tính của đối tượng; trong GraphQL, danh tính được tách rời khỏi cách truy xuất.

So sánh chi tiết
- Endpoint: REST có nhiều URL cho mỗi tài nguyên; GraphQL chỉ có một endpoint duy nhất (thường là
/graphql) - Lấy dữ liệu: REST trả về toàn bộ tài nguyên theo định dạng server định nghĩa; GraphQL trả về đúng dữ liệu client yêu cầu
- Phiên bản: REST cần quản lý versioning (v1, v2…); GraphQL tránh được nhờ schema linh hoạt
- Over-fetching: REST thường trả về thừa trường không cần thiết; GraphQL chỉ trả về những gì query yêu cầu
- Under-fetching: REST buộc nhiều call khi dữ liệu liên quan; GraphQL có thể lấy dữ liệu liên quan trong một query duy nhất
Schema Definition – Nền tảng của GraphQL
Schema là trái tim của bất kỳ hệ thống GraphQL nào. Schema định nghĩa các kiểu dữ liệu (types), mối quan hệ giữa chúng, và các thao tác mà client có thể thực hiện. Schema được viết bằng GraphQL Schema Definition Language (SDL), một ngôn ngữ có kiểu mạnh.
Cấu trúc Schema
Schema bao gồm ba thành phần chính: Query (đọc dữ liệu), Mutation (ghi dữ liệu), và Subscription (theo dõi dữ liệu thời gian thực). Mỗi type trong schema khai báo các trường (fields) với kiểu dữ liệu cụ thể như String, Int, Boolean, ID, hoặc các type tự định nghĩa.
Ví dụ schema đơn giản cho một ứng dụng blog:
- Type Post: id (ID), title (String), content (String), author (User)
- Type User: id (ID), name (String), email (String), posts ([Post])
- Query: post(id: ID!): Post, posts: [Post], user(id: ID!): User
- Mutation: createPost(title: String!, content: String!): Post
Schema mạnh mẽ ở chỗ nó đóng vai trò như một hợp đồng (contract) giữa client và server. Khi schema thay đổi, cả hai bên đều biết chính xác tác động. Công cụ introspection cho phép client tự khám phá schema mà không cần tài liệu riêng.
Queries – Đọc dữ liệu
Query là thao tác cơ bản nhất trong GraphQL. Client gửi một truy vấn chứa tên trường cần lấy và các đối số (arguments). Server phản hồi bằng JSON với cấu trúc trùng khớp với query.
Cú pháp cơ bản
Một query đơn giản yêu cầu tên nhân vật: { hero { name } }. Để lấy nhiều trường hơn: { hero { name friends { name } } }. Query hỗ trợ arguments để lọc dữ liệu, aliases để đặt tên lại trường trong response, và variables để truyền giá trị động thay vì nhúng trực tiếp vào chuỗi truy vấn.
Các tính năng nâng cao bao gồm: Fragments (tái sử dụng các đoạn truy vấn), Inline Fragments (xử lý kiểu union/interface), và Directives (@include, @skip) để điều kiện hóa trường trong query.
Mutations – Ghi dữ liệu
Mutation là thao tác ghi dữ liệu: tạo mới, cập nhật, hoặc xóa. Khác với query chỉ đọc, mutation thay đổi trạng thái trên server và thường trả về dữ liệu vừa thao tác.
Ví dụ tạo một bài đánh giá mới: mutation { createReview(episode: EMPIRE, rating: 5) { stars, commentary } }. Mutation cũng hỗ trợ variables, fragments giống như query. Trong schema, mutation được khai báo trong root Mutation type và mỗi field đại diện cho một thao tác nghiệp vụ cụ thể.
Subscriptions – Dữ liệu thời gian thực
Subscription là tính năng mạnh mẽ nhất của GraphQL, cho phép client nhận cập nhật thời gian thực từ server. Khi một sự kiện xảy ra (ví dụ: có đánh giá mới), server tự động gửi dữ liệu đến tất cả client đang theo dõi.
Cách hoạt động
Subscription được định nghĩa trong schema giống như query và mutation, nhưng sử dụng root operation type Subscription. Về giao thức, GraphQL không quy định cụ thể, nhưng thực tế thường được triển khai qua WebSockets hoặc Server-Sent Events (SSE). Cần một pub/sub system ở backend để publish sự kiện và resolver subscription lắng nghe các sự kiện đó.
Ví dụ: khi client tạo review mới qua mutation, server publish sự kiện REVIEW_CREATED đến pub/sub. Subscription field reviewCreated lắng nghe sự kiện này và gửi dữ liệu đến các client đã subscribe. Đây là nền tảng cho tính năng chat, thông báo, dashboard live.
Advantages của GraphQL
- Linh hoạt: Client tự quyết định cần lấy những trường nào, giảm thiểu over-fetching và under-fetching
- Versionless API: Schema có thể phát triển mà không cần tạo phiên bản mới, tránh phá vỡ client cũ
- Strongly typed: Schema có kiểu mạnh giúp phát hiện lỗi sớm, tự động sinh tài liệu API
- Single endpoint: Đơn giản hóa cấu hình server và client so với REST nhiều endpoint
- Time-saving: Giảm số lượng request mạng, đặc biệt trên mobile với kết nối chậm
- Ecosystem phong phú: Các công cụ như Apollo, Relay, GraphiQL hỗ trợ phát triển toàn diện
Use Cases – Ứng dụng thực tế
GraphQL phù hợp cho nhiều loại ứng dụng khác nhau:
Ứng dụng di động (Mobile Apps)
Mobile apps bị giới hạn băng thông và năng lượng pin. GraphQL giúp giảm số request cần thiết bằng cách gom tất cả dữ liệu vào một query duy nhất. Trước khi GraphQL, các app mobile phải gọi nhiều endpoint REST, mỗi endpoint trả về dữ liệu riêng phần.
Dashboard và Real-time Apps
Kết hợp query, mutation và subscription, GraphQL rất phù hợp cho dashboard với dữ liệu cập nhật liên tục: giá chứng khoán, trạng thái đơn hàng, hoạt động mạng xã hội. Subscription giúp đẩy dữ liệu thay vì client phải polling liên tục.
Microservices và API Aggregation
GraphQL có thể đóng vai trò gateway cho nhiều microservices, gom dữ liệu từ nhiều nguồn thành một response duy nhất cho client. Federation cho phép nhiều nhóm đóng góp vào một schema thống nhất.
CMS và Hệ thống quản lý nội dung
Nhiều CMS hiện đại (Strapi, Contentful, WordPress GraphQL) cung cấp GraphQL API để client linh hoạt truy vấn nội dung theo nhu cầu hiển thị cụ thể.
Bắt đầu với GraphQL
Để bắt đầu, bạn có thể sử dụng các server GraphQL phổ biến: Apollo Server (Node.js), graphql-java (Java), Graphene (Python), Laravel GraphQL (PHP). Các công cụ dev như GraphiQL hoặc GraphQL Playground cung cấp giao diện tương tác để test query và khám phá schema trực quan.
GraphQL không thay thế REST trong mọi trường hợp. REST vẫn phù hợp cho các thao tác đơn giản, cache dễ dàng, hoặc khi cần tích hợp với hệ thống HTTP truyền thống. Tuy nhiên, cho các ứng dụng phức tạp với nhiều mối quan hệ dữ liệu, GraphQL là lựa chọn vượt trội.

Kết luận
GraphQL mang đến một bước chuyển mình trong cách xây dựng API. Với schema mạnh mẽ, khả năng truy vấn linh hoạt, và hỗ trợ subscription thời gian thực, GraphQL giải quyết những điểm yếu lớn nhất của REST truyền thống. Cho dù bạn đang xây dựng app mobile, dashboard real-time, hay hệ thống microservices, GraphQL đều xứng đáng được cân nhắc. Hãy bắt đầu từ một schema đơn giản, thử nghiệm với các query cơ bản, và dần dần mở rộng theo nhu cầu dự án.
Tham khảo thêm
- Tài liệu chính thức GraphQL: https://graphql.org/learn/
- So sánh GraphQL vs REST – Apollo: https://www.apollographql.com/blog/graphql/graphql-vs-rest/
- Hướng dẫn Query – GraphQL: https://graphql.org/learn/queries/
- Subscription trong GraphQL: https://graphql.org/learn/subscriptions/
