REST API — là một phong cách kiến trúc tương tác giữa các thành phần trong mạng phân tán, dựa trên các nguyên tắc của Kiến trúc Hướng tài nguyên và sử dụng giao thức HTTP để truyền dữ liệu. Mỗi tài nguyên trong REST được xác định bằng một URL duy nhất và hỗ trợ một tập hợp các thao tác tiêu chuẩn thông qua các phương thức HTTP: GET, POST, PUT, PATCH, DELETE. Theo ProgrammableWeb (2025), hơn 75% tổng số API web công cộng được xây dựng trên kiến trúc REST, biến nó thành tiêu chuẩn thực tế cho phát triển di động và web. REST đảm bảo khả năng mở rộng, tính độc lập giữa máy khách và máy chủ và bộ nhớ đệm hiệu quả, điều đặc biệt quan trọng đối với các ứng dụng di động có kết nối mạng không ổn định.
Những điểm chính
REST API (API Chuyển giao Trạng thái Biểu diễn) là một phong cách kiến trúc được Roy Fielding đề xuất trong luận án tiến sĩ của ông vào năm 2000. Nó định nghĩa một tập hợp các ràng buộc và nguyên tắc để thiết kế các giao thức mạng. API tuân thủ các ràng buộc này được gọi là RESTful. REST không phải là giao thức hay tiêu chuẩn — nó là một cách tiếp cận kiến trúc sử dụng các giao thức hiện có (chủ yếu là HTTP) để trao đổi dữ liệu giữa máy khách và máy chủ.
Ý tưởng cốt lõi của REST là kiến trúc hướng tài nguyên. Thay vì gọi các phương thức trên máy chủ (như trong SOAP hoặc RPC), máy khách thao tác trên các tài nguyên: lấy danh sách, tạo mới, cập nhật hoặc xóa. Mỗi tài nguyên là một thực thể miền: người dùng, đơn hàng, sản phẩm, bài viết. Một tài nguyên có trạng thái được truyền đến máy khách ở định dạng chuẩn hóa, thường là JSON. Máy chủ không lưu trữ trạng thái của máy khách giữa các yêu cầu — đây là nguyên tắc stateless, một yêu cầu chính của REST.
Các đặc điểm chính của REST API:
REST dựa trên sáu ràng buộc kiến trúc do Fielding xây dựng. Việc tuân thủ các ràng buộc này đảm bảo khả năng mở rộng, hiệu suất và dễ dàng tích hợp. Mỗi nguyên tắc giải quyết một vấn đề cụ thể của hệ thống phân tán — từ nhu cầu lưu vào bộ nhớ đệm đến yêu cầu bảo mật. Hãy xem xét từng nguyên tắc một cách chi tiết.
| Nguyên tắc | Mô tả | Vấn đề giải quyết |
|---|---|---|
| Client-Server | Tách biệt máy khách và máy chủ, tiến hóa độc lập | Liên kết thành phần |
| Stateless | Mỗi yêu cầu chứa tất cả dữ liệu để xử lý | Mở rộng máy chủ |
| Cacheable | Phản hồi được đánh dấu là có thể lưu vào bộ nhớ đệm hay không | Giảm tải mạng |
| Layered System | Các lớp trung gian không hiển thị với máy khách | Bảo mật và cân bằng tải |
| Uniform Interface | Giao diện thống nhất: tài nguyên, phương thức, mã trạng thái | Đơn giản hóa kiến trúc |
| Code on Demand | Tùy chọn: truyền mã thực thi đến máy khách | Khả năng mở rộng phía máy khách |
Nguyên tắc Uniform Interface bao gồm thêm bốn ràng buộc phụ: xác định tài nguyên qua URI, thao tác tài nguyên thông qua biểu diễn, thông điệp tự mô tả và HATEOAS (Siêu phương tiện là Công cụ của Trạng thái Ứng dụng). Ràng buộc phụ cuối cùng thường bị bỏ qua trong thực tế — hầu hết các REST API hiện đại không triển khai đầy đủ HATEOAS, dẫn đến các cuộc thảo luận về việc liệu API đó có “thực sự” RESTful hay không.
Nguyên tắc Stateless là một trong những nguyên tắc quan trọng nhất để mở rộng quy mô. Việc không có phiên trên máy chủ có nghĩa là bất kỳ phiên bản máy chủ nào cũng có thể xử lý bất kỳ yêu cầu nào. Điều này đơn giản hóa việc mở rộng theo chiều ngang: chỉ cần thêm các máy chủ mới sau bộ cân bằng tải. Đối với ứng dụng di động, stateless cũng có nghĩa là yêu cầu có thể được gửi đến bất kỳ máy chủ CDN nào, điều này rất quan trọng cho khả năng truy cập toàn cầu.
Mỗi phương thức HTTP trong REST API tương ứng với một thao tác cụ thể trên tài nguyên: GET để đọc, POST để tạo, PUT để cập nhật toàn bộ, PATCH để cập nhật một phần, DELETE để xóa. Tính chất đẳng năng (idempotence) của các phương thức là một đặc điểm chính: GET, PUT, DELETE là đẳng năng (thực thi nhiều lần cho cùng kết quả), POST và PATCH thì không. Điều này quan trọng để xử lý lỗi mạng khi máy khách không biết yêu cầu đã đến máy chủ hay chưa.
Mã trạng thái HTTP là một phần không thể thiếu của REST API. Mỗi mã mang một ý nghĩa cụ thể: 200 OK cho GET thành công, 201 Created cho POST, 204 No Content cho DELETE không có nội dung phản hồi, 400 Bad Request cho dữ liệu không hợp lệ, 401 Unauthorized khi thiếu xác thực, 404 Not Found khi không tìm thấy tài nguyên. Sử dụng đúng mã trạng thái giúp API tự tài liệu hóa và đơn giản hóa việc gỡ lỗi.
JSON (Ký hiệu Đối tượng JavaScript) là định dạng chính để truyền dữ liệu trong REST API. Sự phổ biến của nó đến từ tính đơn giản, dễ đọc và hỗ trợ gốc trong JavaScript. JSON được truyền với tiêu đề Content-Type: application/json. Các lựa chọn thay thế bao gồm XML (dài dòng, lỗi thời), YAML (tiện lợi cho cấu hình, ít phổ biến cho API) và Protocol Buffers (nhị phân, hiệu quả cho hệ thống tải cao).
Cấu trúc của một đối tượng JSON trong REST API thường bao gồm các trường id, type và các thuộc tính của tài nguyên. Đối với tập hợp, một mảng JSON với siêu dữ liệu phân trang được sử dụng. Các REST API hiện đại tuân theo đặc tả JSON:API (jsonapi.org) hoặc JSON Schema để xác thực phản hồi. Sử dụng định dạng dữ liệu thống nhất giúp đơn giản hóa việc phát triển thư viện máy khách và tạo tài liệu.
Ví dụ về phản hồi JSON cho danh sách người dùng:
{
"data": [
{
"id": 1,
"name": "Anna Petrova",
"email": "anna@example.com"
}
],
"meta": {
"total": 42,
"page": 1,
"per_page": 10
}
}
Việc lựa chọn định dạng truyền dữ liệu ảnh hưởng đến hiệu suất của ứng dụng di động. JSON được nén qua GZIP từ 70-80%, khiến nó chấp nhận được cho hầu hết các kịch bản. Đối với các ứng dụng thời gian thực với khối lượng dữ liệu lớn (phát trực tuyến, trò chơi), nên chuyển sang giao thức nhị phân hoặc sử dụng WebSocket kết hợp với Protocol Buffers.
Hãy xem các ví dụ thực tế về làm việc với REST API ở phía ứng dụng di động. Làm ví dụ, hãy lấy một API để làm việc với các đơn hàng trong cửa hàng trực tuyến. Đối với mỗi phương thức HTTP, một yêu cầu và phản hồi máy chủ dự kiến được hiển thị. Các ví dụ minh họa cấu trúc RESTful API điển hình được sử dụng trong phát triển di động.
Yêu cầu lấy tất cả đơn hàng của người dùng với phân trang. Phản hồi chứa một mảng các đối tượng đơn hàng và siêu thông tin để điều hướng trang. Các tham số page và per_page được truyền qua chuỗi truy vấn.
// Giao diện Retrofit cho REST API
interface OrderApi {
@GET("api/v1/orders")
suspend fun getOrders(
@Query("page") page: Int = 1,
@Query("per_page") perPage: Int = 20
): Response<OrderListResponse>
}
Tạo đơn hàng mới qua yêu cầu POST. Máy chủ trả về trạng thái 201 Created và đối tượng đã tạo trong nội dung phản hồi. Quan trọng: việc tạo được thực hiện trên tập hợp /api/v1/orders, không phải trên một tài nguyên cụ thể — đây là mẫu RESTful tiêu chuẩn.
@POST("api/v1/orders")
suspend fun createOrder(
@Body order: CreateOrderRequest
): Response<OrderResponse>
// Ví dụ về nội dung yêu cầu
data class CreateOrderRequest(
val productId: String,
val quantity: Int,
val addressId: String
)
Việc xóa tài nguyên được thực hiện bằng phương thức DELETE trên URL đơn hàng cụ thể. Xóa thành công trả về 204 No Content. Tính đẳng năng của DELETE có nghĩa là yêu cầu lặp lại đến cùng URL trả về 404 Not Found, được xử lý đúng cách trên máy khách.
@DELETE("api/v1/orders/{id}")
suspend fun deleteOrder(
@Path("id") orderId: String
): Response<Unit>
// Sử dụng trong ViewModel
fun removeOrder(orderId: String) {
viewModelScope.launch {
val response = api.deleteOrder(orderId)
if (response.isSuccessful) {
showSuccess()
}
}
}
Các ví dụ này minh họa một triển khai REST API điển hình trên Android sử dụng Retrofit và Kotlin Coroutines. Đối với ứng dụng iOS, URLSession hoặc thư viện Alamofire kết hợp với các giao thức Codable đóng vai trò tương tự. Cấu trúc REST API vẫn giống nhau bất kể nền tảng — chỉ có cách thực hiện yêu cầu thay đổi.
Thiết kế một API RESTful chất lượng cao đòi hỏi tuân theo các quy ước làm cho API trực quan đối với nhà phát triển. Các tài nguyên nên được đặt tên bằng danh từ số nhiều (/users, /orders, /products), các phương thức HTTP nên phản ánh thao tác và URL nên thể hiện hệ thống phân cấp lồng nhau. Lỗi nên trả về JSON chuẩn hóa với mã và thông báo, không chỉ là trạng thái HTTP. Tuân thủ các quy ước này làm giảm rào cản gia nhập cho nhà phát triển mới và đơn giản hóa việc tích hợp.
Một lỗi phổ biến khi thiết kế REST API là lồng ghép tài nguyên quá mức. Thay vì /users/1/orders/5/items/3, tốt hơn nên sử dụng cấu trúc phẳng với tham số truy vấn: /items?order_id=5&user_id=1. Điều này đơn giản hóa việc lưu vào bộ nhớ đệm, không cần duy trì đường dẫn dài trên máy chủ và dễ tài liệu hóa hơn. Kiến trúc phẳng cũng tương thích tốt hơn với truy vấn dựa trên đồ thị khi chuyển sang GraphQL trong tương lai.
Bảo mật REST API được triển khai thông qua xác thực (JWT, OAuth 2.0) và ủy quyền ở cấp độ tài nguyên. Mỗi yêu cầu phải kiểm tra xem người dùng có quyền truy cập vào tài nguyên được yêu cầu hay không. HTTPS là bắt buộc — nếu không có mã hóa, token và dữ liệu được truyền dưới dạng văn bản thuần túy. Đối với ứng dụng di động, nên sử dụng OAuth 2.0 với PKCE (Proof Key for Code Exchange) để lấy token an toàn.
Quản lý phiên bản của REST API là cần thiết cho khả năng tương thích ngược khi thay đổi. Các cách tiếp cận phổ biến nhất là: phiên bản trong URL (/api/v1/orders), phiên bản trong tiêu đề (Accept: application/vnd.myapi.v1+json) và phiên bản trong tham số truy vấn (?api_version=1). Quản lý phiên bản qua URL là phương pháp phổ biến nhất vì nó hiển thị rõ ràng trong nhật ký và tài liệu. Tuy nhiên, nó vi phạm nguyên tắc REST về một URL duy nhất cho mỗi tài nguyên.
Bộ nhớ đệm trong REST API được triển khai qua các tiêu đề HTTP Cache-Control, ETag và Last-Modified. Các yêu cầu GET được đánh dấu là có thể lưu vào bộ nhớ đệm có thể được phục vụ từ bộ nhớ đệm của trình duyệt hoặc proxy mà không cần liên hệ với máy chủ. Đối với ứng dụng di động, bộ nhớ đệm đặc biệt quan trọng — nó giảm tiêu thụ dữ liệu và tăng tốc hiển thị dữ liệu đã tải trước đó khi kết nối kém. ETag là hàm băm của nội dung phản hồi: máy khách gửi nó trong If-None-Match và máy chủ trả về 304 Not Modified nếu dữ liệu không thay đổi.
Các lựa chọn thay thế hiện đại cho REST API bao gồm GraphQL (lấy dữ liệu linh hoạt từ phía máy khách) và gRPC (giao thức nhị phân trên HTTP/2 cho microservice). Tuy nhiên, REST vẫn là tiêu chuẩn chính cho các API công cộng nhờ tính đơn giản, tính phổ quát và hỗ trợ công cụ rộng rãi. Việc lựa chọn giữa REST và các lựa chọn thay thế phụ thuộc vào yêu cầu cụ thể của dự án: độ phức tạp của truy vấn, khối lượng dữ liệu, nhu cầu cập nhật thời gian thực.
Các câu hỏi thường gặp
REST là một phong cách kiến trúc, một tập hợp các nguyên tắc. RESTful là một API tuân thủ các nguyên tắc này. API RESTful tuân thủ stateless, giao diện thống nhất, bộ nhớ đệm và kiến trúc máy khách-máy chủ.
JSON nhẹ hơn XML (~30% nhỏ hơn), phân tích nhanh hơn và có hỗ trợ gốc trong JavaScript. XML vẫn được sử dụng trong SOAP và hệ thống kế thừa, nhưng JSON là tiêu chuẩn cho API di động.
Sử dụng HTTPS để mã hóa, JWT hoặc OAuth 2.0 để xác thực. Thêm giới hạn tốc độ, xác thực đầu vào, chính sách CORS và kiểm tra vai trò trên mỗi yêu cầu.
HATEOAS là nguyên tắc trong đó phản hồi API chứa các liên kết đến tài nguyên liên quan. Máy khách “điều hướng” API qua các liên kết này thay vì URL đã biết trước. Trong thực tế, HATEOAS hiếm khi được triển khai đầy đủ.
Nếu cần lấy dữ liệu linh hoạt — chuyển sang GraphQL. Để hiệu suất cao giữa các microservice — gRPC. Để cập nhật thời gian thực — WebSocket. REST là tối ưu cho hầu hết các API công cộng.
Tổng kết
Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay
IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.
Đọc thêm