GraphQL so với REST: khi nào dùng gì

So sánh toàn diện kiến trúc REST và GraphQL

Trong thiết kế ứng dụng mạng (Web API), việc lựa chọn giữa giao thức truyền thống REST (Representational State Transfer) và GraphQL (giao thức truy vấn dữ liệu do Facebook phát triển) là một chủ đề tranh luận quen thuộc của giới kiến trúc phần mềm. Cả hai đều có điểm mạnh và điểm yếu riêng biệt.

1. Sự khác biệt cốt lõi

  • REST (Resource-based): Gom dữ liệu theo từng Resource (Resource URL). Lấy danh sách bài viết gọi GET /posts, chi tiết bài viết gọi GET /posts/{id}, thông tin tác giả gọi GET /users/{id}. Client phải gọi nhiều request nối tiếp nhau để hiển thị được đầy đủ thông tin (gây ra lỗi Under-fetching).
  • GraphQL (Query-based): Chỉ có duy nhất một API Endpoint (thường là POST /graphql). Client tự định nghĩa một cấu trúc JSON truy vấn để yêu cầu server trả đúng những gì mình muốn (tránh Over-fetching - lấy thừa dữ liệu không dùng tới).

2. Code thực hành so sánh

Giả sử ta cần lấy tiêu đề bài viết và tên của tác giả bài viết đó:

REST API (Multiple Requests) GraphQL Query (One Request)
// Request 1: GET /api/posts/42
{
  "id": 42,
  "title": "GraphQL vs REST",
  "author_id": 7,
  "views": 1500,
  "content": "..."
}

// Request 2: GET /api/users/7
{
  "id": 7,
  "name": "duytran7",
  "role": "author"
}
# Request: POST /api/graphql
query {
  post(id: 42) {
    title
    author {
      name
    }
  }
}

# Response:
{
  "data": {
    "post": {
      "title": "GraphQL vs REST",
      "author": { "name": "duytran7" }
    }
  }
}

3. Các thách thức kỹ thuật lớn của GraphQL

GraphQL không phải là chiếc đũa thần giúp giải quyết mọi vấn đề. Nó mang lại một số khó khăn nghiêm trọng:

  1. Lỗi N+1 Queries: Khi resolve dữ liệu quan hệ (ví dụ: lấy 10 bài viết và tác giả của chúng), nếu không tối ưu, ORM sẽ thực thi 1 câu SELECT lấy 10 bài, rồi lặp 10 lần SELECT để lấy từng tác giả. Để khắc phục, ta buộc phải dùng giải pháp gom nhóm truy vấn (Batching) thông qua thư viện DataLoader của GraphQL.
  2. HTTP Caching khó khăn: Vì mọi request của GraphQL đều dùng phương thức POST, các hệ thống CDN (Cloudflare) hay Browser không thể tự động cache dữ liệu như REST (dùng HTTP GET). Ta phải dùng giải pháp thay thế phức tạp như Persisted Queries.
  3. Tấn công từ chối dịch vụ (Query Complexity): Client có thể gửi một câu query lồng nhau vô tận để đánh sập RAM của server:
    query {
      user {
        posts {
          author {
            posts {
              author { # Lồng vô hạn...
              }
            }
          }
        }
      }
    }
    Để bảo mật, ta phải cấu hình giới hạn độ sâu (Query Depth Limit) và độ phức tạp (Query Complexity Analysis).

4. Bảng quyết định kiến trúc: Khi nào dùng gì?

Kiến trúc thích hợp GraphQL REST API
Loại ứng dụng Ứng dụng đa nền tảng (Web, App Mobile, Watch) cùng đọc dữ liệu từ một chỗ. Các ứng dụng CRUD cơ bản, dịch vụ Microservices nội bộ giao tiếp với nhau.
Caching yêu cầu Chủ yếu cache phía client (như Apollo Client, Relay). Tận dụng tối đa HTTP Cache, CDN Varnish/Squid ở biên.
Tốc độ phát triển Nhanh ở phía frontend vì không cần chờ backend viết endpoint mới. Đòi hỏi thiết kế và document (OpenAPI) trước khi bắt đầu.

Bình luận (0)

Đang tải bình luận...