REST, GraphQL, gRPC, tRPC: xu hướng thiết kế API và cách chọn

  • author-image

    Nguyễn Đình Cường

  • blog-tag
  • blog-comment 0 comment
  • created-date 09 Nov, 2026
blog-thumbnail

API là cầu nối giữa các phần mềm, và cách thiết kế nó ảnh hưởng lớn đến tốc độ phát triển lẫn hiệu năng. REST vẫn phổ biến, nhưng GraphQL, gRPC và tRPC đã xuất hiện để giải quyết những điểm đau cụ thể. Bài này so sánh bốn cách tiếp cận để bạn chọn đúng thay vì chạy theo xu hướng.

REST: đơn giản và phổ biến

REST tổ chức API quanh các tài nguyên và phương thức HTTP (GET, POST, PUT, DELETE). Dữ liệu thường là JSON. Nó dễ hiểu, tận dụng được cache của HTTP và công cụ hỗ trợ rất nhiều.

GET  /api/users/42          -> lấy người dùng 42
POST /api/users             -> tạo người dùng
GET  /api/users/42/orders   -> đơn hàng của người dùng 42

Hạn chế: có thể lấy thừa dữ liệu (over-fetching), hoặc phải gọi nhiều endpoint để ghép một màn hình (under-fetching).

GraphQL: khách hàng chọn dữ liệu

GraphQL cho phép client mô tả chính xác dữ liệu cần lấy trong một truy vấn duy nhất:

query {
  user(id: 42) {
    name
    orders(last: 3) {
      id
      total
    }
  }
}

Ưu điểm: giảm số lần gọi, linh hoạt cho nhiều loại client (web, di động). Cái giá phải trả: phức tạp hơn ở phía máy chủ, khó dùng cache HTTP thông thường và cần chú ý giới hạn độ sâu truy vấn, hiệu năng (vấn đề N+1) và phân quyền theo từng trường.

gRPC: nhanh và có hợp đồng chặt chẽ

gRPC dùng Protocol Buffers để định nghĩa dịch vụ và truyền dữ liệu nhị phân gọn nhẹ qua HTTP/2. Hợp đồng được mô tả trong file .proto, từ đó sinh code cho nhiều ngôn ngữ:

syntax = "proto3";

service UserService {
  rpc GetUser (GetUserRequest) returns (User);
}

message GetUserRequest { int32 id = 1; }
message User { int32 id = 1; string name = 2; }

Phù hợp giao tiếp giữa các dịch vụ nội bộ cần hiệu năng cao và hỗ trợ streaming. Với trình duyệt, việc dùng trực tiếp phức tạp hơn nên cần lớp trung gian.

tRPC: an toàn kiểu từ đầu đến cuối trong TypeScript

tRPC cho phép client TypeScript gọi hàm trên server như gọi hàm thường, với kiểu dữ liệu được suy ra tự động mà không cần schema riêng. Nó rất tiện cho dự án full-stack dùng chung một repo TypeScript. Giới hạn: gắn chặt với hệ sinh thái TypeScript, không phù hợp nếu client viết bằng ngôn ngữ khác hay cần công khai API cho bên thứ ba.

Bảng so sánh

Tiêu chíRESTGraphQLgRPCtRPC
Độ đơn giảnRất caoTrung bìnhTrung bìnhCao (nếu dùng TS)
Linh hoạt truy vấnThấpRất caoTrung bìnhCao
Hiệu năng truyềnTốtTốtRất tốtTốt
API công khaiRất phù hợpPhù hợpHạn chếKhông phù hợp

Cách chọn thực dụng

  1. API công khai hoặc dự án nhỏ: bắt đầu với REST.
  2. Nhiều client khác nhau cần dữ liệu khác nhau, màn hình ghép nhiều nguồn: cân nhắc GraphQL.
  3. Dịch vụ nội bộ cần nhanh, hợp đồng chặt: gRPC.
  4. Full-stack TypeScript trong cùng repo: tRPC rất gọn.

Cũng có thể kết hợp: REST cho API công khai, gRPC giữa các dịch vụ nội bộ.

Những điều áp dụng cho mọi kiểu API

  • Xác thực và phân quyền rõ ràng ở từng thao tác.
  • Kiểm tra đầu vào, trả lỗi nhất quán.
  • Quản lý phiên bản để không phá vỡ client cũ.
  • Tài liệu và ví dụ đầy đủ.
  • Giới hạn tốc độ và ghi log để vận hành an toàn.

Câu hỏi thường gặp

GraphQL có sẽ thay thế REST không?

Rất khó. REST đơn giản, phổ biến và tận dụng tốt HTTP nên vẫn là lựa chọn mặc định cho nhiều API.

Có thể dùng nhiều kiểu API trong cùng một hệ thống không?

Có. Nhiều hệ thống dùng REST cho bên ngoài và gRPC cho giao tiếp nội bộ, miễn là có tài liệu và quy ước rõ ràng.

Kết luận

Không có kiểu API thắng tuyệt đối. REST giữ vị trí vững vì đơn giản, các lựa chọn khác tỏa sáng ở bài toán cụ thể. Hiểu điểm mạnh và giá phải trả của từng loại giúp bạn quyết định dựa trên nhu cầu thật của dự án.

Muốn học thiết kế và xây dựng API từ cơ bản đến nâng cao, mời bạn xem các khóa học backend tại codebem.com.

author_photo
Nguyễn Đình Cường

0 comment