Kiến thức cơ bản về API: API là gì?
TỔNG QUÁT:
Trong thời đại phát triển phần mềm hiện nay, API (Application Programming Interface) đóng vai trò then chốt, giúp các ứng dụng, dịch vụ và hệ thống khác nhau có thể "nói chuyện" và trao đổi dữ liệu với nhau một cách hiệu quả.
Trước tiên đi vào khái niệm của từng kiểu API cơ bản, thì đầu tiên bạn cần hiểu API là gì?
- API là gì ?
- API là viết tắt của Application Programming Interface – Giao diện lập trình ứng dụng.
- Là tập hợp các quy tắc và phương thức cho phép các phần mềm khác nhau tương tác, trao đổi dữ liệu với nhau.
- API hoạt động như thế nào?
- Khi 1 client gửi 1 request tới server thì API sẽ là người trung gian giữa client và server để xử lý các yêu cầu như:
- Request nào có thể thực hiện
- Cách nào để thực hiện request
- Response nào để nhận lại
- Hầu hết các API hiện đại hoạt động dựa trên giao thức HTTP/HTTPS, và thường trao đổi dữ liệu dưới dạng JSON (đôi khi là XML hoặc binary).

- Tại sao cần nhiều kiểu API khác nhau?
- Tùy thuộc vào nhu cầu cụ thể về hiệu năng, tính linh hoạt, lượng dữ liệu, môi trường triển khai (public API hay internal microservices), các lập trình viên đã thiết kế ra nhiều kiểu (style) API khác nhau.
- Trong bài viết này, chúng ta sẽ tìm hiểu sâu về ba kiểu API phổ biến và quan trọng nhất hiện nay:
- REST API — Kiểu cổ điển, dễ hiểu và được sử dụng rộng rãi nhất.
- GraphQL — Kiểu linh hoạt, cho phép client tự định nghĩa dữ liệu cần lấy.
- gRPC — Kiểu hiệu năng cao, phù hợp cho giao tiếp giữa các microservices.
- Sau khi đọc xong, bạn sẽ hiểu rõ ưu nhược điểm của từng kiểu và biết khi nào nên dùng kiểu nào trong dự án thực tế.
I. REST API:
- Khái niệm:
- Representational State Transfer là 1 phong cách kiến trúc trong đó tài nguyên được truy cập và thao tác thông qua HTTP bằng cách sử dụng các phương thức chuẩn như GET, POST, PUT, DELETE.
- Cấu trúc hoạt động:
Mỗi tài nguyên được biểu diễn bằng một đường dẫn (endpoint) duy nhất, và có thể truy cập hoặc thao tác thông qua các phương thức HTTP chuẩn như:
Phương thức Chức năng Ví dụ GET Lấy dữ liệu của tài nguyên GET /users– Lấy danh sách người dùngPOST Tạo mới tài nguyên POST /users– Tạo người dùng mớiPUT Cập nhật toàn bộ tài nguyên PUT /users/1– Cập nhật thông tin người dùng #1PATCH Cập nhật một phần tài nguyên PATCH /users/1– Cập nhật riêng email của người dùngDELETE Xóa tài nguyên DELETE /users/1– Xóa người dùng có ID = 1Quy trình hoạt động cơ bản:
- Client gửi request với HTTP method + URL + (có thể có body và query params).
- Server xác định tài nguyên dựa trên URL và method.
- Server gọi service/business logic → tương tác với Database.
- Trả về response dưới dạng JSON (thường gặp nhất) kèm HTTP Status Code để thể hiện kết quả.
| STATUS CODE | Chức năng | Ví dụ |
|---|---|---|
| 2xx | Success | 200 OK – Thành công |
201 Created – Đã tạo mới | ||
| 3xx | Redirection | 301 Moved Permanently - Chuyển hướng vĩnh viễn sang URL mới |
| 4xx | Client Error | 400 Bad Request – Dữ liệu sai |
404 Not Found – Không tìm thấy tài nguyên | ||
| 5xx | Server Error | 500 Internal Server Error – Lỗi phía server |

Ví dụ:

Giải thích:
- Client gửi request với method GET → ý định lấy dữ liệu.
- Server đọc URL và method, truy vấn database, trả về JSON chứa đúng thông tin sản phẩm.
- Nếu không tìm thấy: trả về 404 Not Found. 4. Ứng dụng:
Public APIs (Twitter/X API, GitHub API, Stripe...).
Web services, backend cho mobile/web apps.
- Ưu điểm/nhược điểm:
a. Ưu điểm:
Dễ hiểu, dễ học và triển khai.
Phổ biến, cộng đồng hỗ trợ lớn, tương thích cao với mọi ngôn ngữ và client (browser, mobile...).
Stateless → dễ scale ngang (horizontal scaling).
Hỗ trợ caching tốt qua HTTP headers.
Có thể test dễ dàng bằng công cụ như Postman, curl.
b. Nhược điểm:
Dễ gặp over-fetching (lấy thừa dữ liệu) và under-fetching (phải gọi nhiều request).
Số lượng endpoint có thể tăng nhiều khi ứng dụng phức tạp.
Không tối ưu cho realtime (cần kết hợp WebSocket).
Versioning và quản lý thay đổi có thể phức tạp theo thời gian.
II. GraphQl:
- Khái niệm:
- GraphQL là một ngôn ngữ truy vấn dữ liệu, cho phép client yêu cầu chính xác dữ liệu mà họ cần từ server, chỉ thông qua một endpoint duy nhất (
/graphql). - Client gửi một truy vấn (query) mô tả cấu trúc dữ liệu mong muốn, server sẽ trả về đúng những trường đó, không thừa, không thiếu. 2. Kiến trúc:
GraphQL bao gồm ba phần chính:
a. Schema: Định nghĩa các kiểu dữ liệu (types), các truy vấn (queries), các thao tác thay đổi (mutations) và mối quan hệ giữa chúng.
b. Resolvers: Hàm xử lý logic cho từng trường trong schema. Chúng quyết định dữ liệu được lấy từ đâu (database, service khác…).
c. Runtime: Engine thực thi truy vấn GraphQL và trả về kết quả.
Các loại thao tác (Operations) chính
- Query: dùng để lấy dữ liệu từ API (tương đương GET trong REST)
query {
getTodos {
id
title
completed
}
}
- Mutation: dùng để thực hiện các thay đổi dữ liệu (tương đương POST, PUT, DELETE)
mutation {
addTodo(title: "Learn GraphQL") {
id
title
completed
}
}
- Subscription: dùng để nhận dữ liệu thời gian thực khi có thay đổi:
subscription {
onPostAdded {
id
title
author {
name
}
}
}
- Cấu trúc hoạt động:
- Client gửi truy vấn đến endpoint /graphql.
- Server nhận truy vấn, kiểm tra tính hợp lệ theo Schema.
- Dựa vào Resolvers, server thu thập dữ liệu từ nhiều nguồn (có thể từ nhiều bảng database chỉ trong một request).
- Trả về response dưới dạng JSON với cấu trúc đúng như client yêu cầu. 4. Ví dụ:
Request:
query {
user(id: 1) {
id
name
}
}
Response:
{
"data": {
"user": {
"id": 1,
"name": "Dimori"
}
}
}

- Ứng dụng:
Ứng dụng mạng xã hội (Facebook, Instagram).
E-commerce phức tạp (Shopify).
Ứng dụng mobile/web cần dữ liệu linh hoạt và giảm số lượng request.
- Ưu và nhược điểm:
a. Ưu điểm
Chỉ một endpoint duy nhất cho toàn bộ API.
Tránh over-fetching và under-fetching: client chỉ nhận đúng dữ liệu cần.
Giảm số lượng request (một query có thể lấy nhiều thông tin liên quan).
Schema rõ ràng, tự động sinh tài liệu (GraphQL Playground, Apollo Studio).
Hỗ trợ mạnh mẽ cho versioning (thêm field mới mà không phá vỡ client cũ).
Giải quyết tốt vấn đề N+1 query khi thiết kế resolver đúng cách.
b. Nhược điểm
Khó triển khai và debug hơn REST (đặc biệt với người mới).
Không tận dụng được cơ chế cache HTTP thông thường (cần cache layer riêng như Apollo Cache hoặc Redis).
Dễ bị query quá sâu (deep nesting) hoặc query quá phức tạp nếu server không có giới hạn (rate limiting, query complexity).
Luôn trả về HTTP status code 200 OK, dù query thành công hay thất bại. Lỗi được trả về trong trường "errors" → cần xử lý lỗi cẩn thận ở client.
III. gRPC:
- Khái niệm:
- RPC (Remote Procedure Call) là một mô hình kỹ thuật mạng, là giao thức giao tiếp giữa các phần mềm (hoặc process - tiến trình) mà một chương trình có thể yêu cầu một dịch vụ từ một chương trình khác nằm trong một máy tính/máy chủ khác hay hiểu đơn giản là phương pháp gọi hàm từ một máy tính ở xa để lấy về kết quả.
- Google Remote Procedure Call (gRPC) là một framework giao tiếp hiệu năng cao do Google phát triển, cho phép các ứng dụng gọi hàm hoặc phương thức từ xa như thể chúng đang nằm trong cùng một chương trình. 2. Cấu trúc hoạt động:
- Định nghĩa dịch vụ (service definition): Nhà phát triển mô tả các hàm (RPC – Remote Procedure Calls) mà server cung cấp trong một file
.proto. Điều này giúp hai bên (client và server) hiểu nhau một cách chính xác và type-safe.
Ví dụ về file .proto:
syntax = "proto3";
service UserService {
rpc GetUser (UserRequest) returns (UserResponse);
}
message UserRequest {
int32 id = 1;
}
message UserResponse {
int32 id = 1;
string name = 2;
string email = 3;
}
Tạo mã nguồn tự động (code generation): Từ file
.proto, gRPC tự sinh code client và server tương ứng cho nhiều ngôn ngữ (Go, Java, C#, Node.js, Python...).Quy trình hoạt động:
Client-side: Ứng dụng gọi một phương thức được sinh ra bởi Stub. Stub sẽ đóng gói các tham số vào định dạng Protobuf (Binary).
Encoding (Mã hóa): Dữ liệu được chuyển thành Protocol Buffers (Protobuf) – định dạng nhị phân nhỏ gọn, nhanh chóng và tiết kiệm băng thông hơn nhiều so với JSON.
gRPC Runtime & Transport: Dữ liệu binary được gửi qua giao thức HTTP/2 (hỗ trợ nhiều request cùng lúc trên một kết nối, nén header, và streaming).
Server-side: gRPC Runtime nhận dữ liệu, giải mã (decode) từ Protobuf sang đối tượng ngôn ngữ lập trình tương ứng và gọi hàm xử lý thực tế trên Server.
Client nhận kết quả: Stub giải mã dữ liệu và trả về cho ứng dụng client dưới dạng object thông thường.

- Ví dụ:
Hãy tưởng tượng trong một hệ thống e-commerce, khi khách hàng đặt hàng, Order Service cần kiểm tra số dư tài khoản và trạng thái thanh toán của khách hàng bằng cách gọi Payment Service.
- Giai đoạn Chuẩn bị: Nhà phát triển dùng file
.prototrên để sinh ra Client Stub cho Order Service (có thể dùng Node.js) và Server Skeleton cho Payment Service (có thể dùng Go).
File .proto:
syntax = "proto3";
service PaymentService {
rpc CheckBalance (BalanceRequest) returns (BalanceResponse);
}
message BalanceRequest {
int32 user_id = 1;
}
message BalanceResponse {
double amount = 1;
bool is_active = 2;
}
- Thực thi cuộc gọi (Call): Trong code của Order Service, lập trình viên chỉ cần gọi hàm
paymentClient.CheckBalance({user_id: 123}). Với họ, việc gọi này giống hệt như gọi một hàm nội bộ (local function), dù Payment Service có thể đang chạy trên server khác. - Mã hóa (Serialization): gRPC Client Stub sẽ lấy số
{ user_id: 123 }, đối chiếu với file định nghĩa và nén nó thành một chuỗi byte nhị phân siêu nhỏ. - Vận chuyển (Transport): Chuỗi byte này được gửi qua luồng HTTP/2 đã thiết lập sẵn. Nhờ HTTP/2, kết nối này không bị đóng lại sau mỗi lần gọi, giúp giảm độ trễ tối đa.
- Xử lý tại Server: Payment Service nhận chuỗi byte, giải mã ngược lại thành số, truy vấn Database và lấy ra số dư.
- Phản hồi (Response): Kết quả (số dư và trạng thái) lại được nén thành nhị phân và gửi ngược về cho Order Service để hoàn tất quy trình đặt hàng. 4. Ứng dụng:
- Giao tiếp nội bộ giữa các microservices (đây là use case phổ biến nhất).
- Hệ thống yêu cầu hiệu năng cao và độ trễ thấp: fintech, trading, IoT, video streaming, gaming backend.
- Ứng dụng cần streaming dữ liệu thời gian thực (bidirectional streaming).
Lưu ý: gRPC ít được dùng cho public API (API dành cho bên thứ ba hoặc browser) vì dữ liệu binary và HTTP/2 không thân thiện với browser.
Ưu và nhược điểm:
a. Ưu điểm:
Hiệu năng vượt trội: Độ trễ thấp, throughput cao nhờ binary + HTTP/2.
Hỗ trợ mạnh mẽ streaming (unary, server, client, bidirectional).
Contract-first với Protobuf → type-safe, tự động sinh code, ít lỗi.
Dễ tích hợp trong môi trường polyglot (đa ngôn ngữ) và microservices.
Hỗ trợ tốt authentication, load balancing, deadlines và cancellation.
b. Nhược điểm:
Không thân thiện với trình duyệt (browser support kém, thường cần gRPC-Web).
Debug khó hơn vì dữ liệu là binary (không đọc được trực tiếp như JSON).
Learning curve cao hơn REST và GraphQL.
Cấu hình và tooling phức tạp hơn khi triển khai production.
Ít phù hợp cho public APIs (thường kết hợp với gateway để chuyển sang REST/GraphQL cho client bên ngoài).
IV. Tổng kết:
| Tiêu chí | REST API | GraphQL | gRPC |
|---|---|---|---|
| Kiến trúc | Resource-based (hướng tài nguyên) | Query-based (hướng truy vấn) | RPC-based (gọi hàm từ xa) |
| Số lượng Endpoint | Nhiều endpoint | Một endpoint duy nhất (/graphql) | Nhiều service/method |
| Giao thức truyền tải | HTTP 1.1 / HTTP 2 | HTTP 1.1 / HTTP 2 | HTTP 2 (Bắt buộc) |
| Định dạng dữ liệu | JSON (Text) | JSON (Text) | Protobuf (Binary) |
| Tính linh hoạt | Trung bình (Fixed) | Rất cao (Client tự chọn) | Thấp (Strict Contract) |
| Hiệu suất & Tốc độ | Khá | Trung bình (do Overhead xử lý Query) | Cực nhanh |
| Độ khó (Learning Curve) | Thấp | Trung bình | Cao |
| Phù hợp với Browser | Rất tốt | Tốt | Kém (cần gRPC-Web) |
| Caching | Tốt (sử dụng HTTP cache) | Trung bình (cần cache layer riêng) | Trung bình |
| Trường hợp sử dụng tốt nhất | Public API, Web App truyền thống | Web/Mobile App cần dữ liệu linh hoạt | Microservices nội bộ, Real-time, IoT |
SUMMARY:
- REST API: Là lựa chọn mặc định và an toàn nhất cho hầu hết các dự án. Nên dùng khi:
- Xây dựng Public API (API cho bên thứ ba).
- Dự án đơn giản đến trung bình, cần tính tương thích cao.
- Đội ngũ mới hoặc muốn phát triển nhanh.
- GraphQL: Nên sử dụng khi:
- Ứng dụng frontend/mobile cần dữ liệu linh hoạt, tránh over-fetching/under-fetching.
- Dự án có nhiều mối quan hệ dữ liệu phức tạp (mạng xã hội, e-commerce, dashboard…).
- Muốn giảm số lượng request giữa client và server.
- gRPC: Là lựa chọn tối ưu nhất khi:
- Xây dựng giao tiếp nội bộ giữa các microservices.
- Hệ thống đòi hỏi hiệu năng cao, độ trễ thấp và throughput lớn (fintech, IoT, gaming, AI…).
- Cần hỗ trợ streaming dữ liệu thời gian thực mạnh mẽ.