Tài Nguyên Trong REST API: Giải Thích Chi Tiết

Iroro Chadere

Iroro Chadere

20 tháng 5 2025

Tài Nguyên Trong REST API: Giải Thích Chi Tiết

Trong phát triển web hiện đại, API Representational State Transfer (REST) đã trở thành tiêu chuẩn thực tế để xây dựng các dịch vụ web có khả năng mở rộng, dễ bảo trì và dễ hiểu. Cốt lõi của bất kỳ API RESTful nào là một khái niệm cơ bản: tài nguyên (resource). Hiểu rõ tài nguyên là gì, cách chúng được xác định và cách chúng ta tương tác với chúng là điều tối quan trọng để thiết kế và sử dụng API REST một cách hiệu quả. Bài viết này sẽ đi sâu vào bản chất của tài nguyên trong API REST, khám phá các đặc điểm, mối quan hệ của chúng với các tập hợp (collections) và các thao tác phổ biến được thực hiện trên chúng.

Ý tưởng cốt lõi đằng sau REST là một API hiển thị một tập hợp các tài nguyên và các client tương tác với các tài nguyên này bằng cách gửi yêu cầu đến các định danh duy nhất của chúng. Nhưng chính xác thì "tài nguyên" bao gồm những gì? Trong bối cảnh của API REST, tài nguyên có thể là hầu hết mọi thứ bạn có thể đặt tên. Nó có thể là một thực thể hữu hình như khách hàng, sản phẩm hoặc đơn hàng. Nó cũng có thể là một khái niệm trừu tượng như dịch vụ, giao dịch hoặc tính toán. Điều quan trọng là nó là một mục quan tâm có thể được xác định và thao tác.

Hãy nghĩ về internet như một tập hợp lớn các tài nguyên. Mỗi trang web, hình ảnh, video hoặc tài liệu bạn truy cập trực tuyến là một tài nguyên, mỗi tài nguyên có địa chỉ duy nhất của riêng nó (URL). API REST áp dụng triết lý tương tự. Cho dù đó là hồ sơ người dùng trên nền tảng mạng xã hội, một cuốn sách cụ thể trong thư viện trực tuyến hay dự báo thời tiết cho một thành phố cụ thể, mỗi thứ đều là một tài nguyên mà API cung cấp.

💡
Bạn muốn một công cụ kiểm thử API tuyệt vời tạo ra Tài liệu API đẹp mắt?

Bạn muốn một nền tảng Tích hợp, Tất cả trong Một để Đội ngũ Phát triển của bạn làm việc cùng nhau với năng suất tối đa?

Apidog đáp ứng mọi nhu cầu của bạn và thay thế Postman với mức giá phải chăng hơn nhiều!
button

Xác định Tài nguyên: Vai trò của URI

Quan trọng là, mỗi tài nguyên trong API REST phải có ít nhất một định danh duy nhất. Định danh này thường là Uniform Resource Identifier (URI). Dạng phổ biến nhất của URI được sử dụng trong các API web là Uniform Resource Locator (URL), không chỉ xác định tài nguyên mà còn cung cấp phương tiện để định vị nó.

Ví dụ, trong API để quản lý blog, một bài đăng blog cụ thể có thể được xác định bằng URI như /posts/123. Ở đây, /posts có thể đại diện cho một tập hợp các bài đăng và 123 là định danh duy nhất cho một bài đăng cụ thể trong tập hợp đó. Tương tự, tài nguyên người dùng có thể được xác định bằng /users/john.doe.

Thiết kế các URI này là một khía cạnh quan trọng của thiết kế API. Các URI được thiết kế tốt thì trực quan, dễ đoán và dễ hiểu, dễ sử dụng đối với các nhà phát triển. Chúng nên hoạt động như một biển chỉ dẫn rõ ràng, cho biết bản chất của tài nguyên đang được truy cập. Thực hành tốt chỉ ra việc sử dụng danh từ để đại diện cho tài nguyên (ví dụ: /products, /orders) thay vì động từ (ví dụ: /getProducts, /createOrder). Các phương thức HTTP (GET, POST, PUT, DELETE) sau đó được sử dụng để chỉ định hành động sẽ được thực hiện trên tài nguyên được xác định bởi URI.

Tài nguyên so với Biểu diễn: Một sự phân biệt quan trọng

Điều quan trọng là phải hiểu sự khác biệt giữa tài nguyên và biểu diễn của nó. Tài nguyên là thực thể khái niệm đó - "thứ" thực tế (khách hàng, sản phẩm, ý tưởng). Mặt khác, biểu diễn là một ảnh chụp nhanh trạng thái của tài nguyên đó tại một thời điểm cụ thể, thường được định dạng theo một kiểu phương tiện cụ thể như JSON (JavaScript Object Notation) hoặc XML (eXtensible Markup Language).

Khi một client yêu cầu một tài nguyên từ API, nó không nhận được chính tài nguyên đó (một khái niệm trừu tượng nằm trên máy chủ). Thay vào đó, nó nhận được một biểu diễn của tài nguyên đó. Ví dụ, nếu bạn yêu cầu /users/jane.doe, API có thể trả về một biểu diễn JSON như sau:JSON

{
  "id": "jane.doe",
  "firstName": "Jane",
  "lastName": "Doe",
  "email": "jane.doe@example.com",
  "dateJoined": "2023-01-15T10:00:00Z"
}

Đối tượng JSON này không phải là chính Jane Doe; đó là biểu diễn dữ liệu của cô ấy được lưu trữ bởi hệ thống. Cùng một tài nguyên có thể có nhiều biểu diễn khác nhau. Ví dụ, API cũng có thể cung cấp biểu diễn XML của cùng một người dùng nếu được client yêu cầu thông qua đàm phán nội dung (sử dụng các tiêu đề HTTP như Accept).

Trạng thái của một tài nguyên có thể thay đổi theo thời gian. Nếu Jane Doe cập nhật địa chỉ email của mình, tài nguyên người dùng cơ bản sẽ thay đổi. Các yêu cầu tiếp theo cho /users/jane.doe sẽ trả về một biểu diễn mới phản ánh trạng thái cập nhật này. Đây là lúc phần "Chuyển đổi Trạng thái" (State Transfer) của REST phát huy tác dụng: các client tương tác với tài nguyên bằng cách truy xuất và thao tác trạng thái của chúng thông qua các biểu diễn này.

Tập hợp (Collections): Tài nguyên chứa các Tài nguyên khác

Thông thường, các tài nguyên được nhóm lại với nhau thành các tập hợp. Một tập hợp bản thân nó cũng là một tài nguyên. Ví dụ, /posts trong API blog của chúng ta là một tài nguyên tập hợp chứa các tài nguyên bài đăng riêng lẻ. Tương tự, /users sẽ là một tập hợp các tài nguyên người dùng.

Khi một client gửi yêu cầu GET đến một URI tập hợp như /products, API thường trả về một biểu diễn liệt kê các tài nguyên thành viên trong tập hợp đó, thường kèm theo một số thông tin tóm tắt cho mỗi tài nguyên. Danh sách này có thể trông giống như sau:JSON

[
  {
    "id": "prod_abc",
    "name": "Laptop Pro 15",
    "price": 1299.99,
    "link": "/products/prod_abc"
  },
  {
    "id": "prod_xyz",
    "name": "Wireless Mouse Ergonomic",
    "price": 39.99,
    "link": "/products/prod_xyz"
  },
  // ... thêm sản phẩm
]

Lưu ý cách mỗi mục trong tập hợp thường bao gồm một liên kết (hoặc URI riêng của nó) đến tài nguyên riêng lẻ, cho phép client điều hướng đến và truy xuất đầy đủ chi tiết của một sản phẩm cụ thể nếu cần.

Thiết kế URI cho các tập hợp và các thành viên của chúng tuân theo một mô hình logic. Thông thường:

Cấu trúc phân cấp này làm cho API trực quan và phù hợp với mối quan hệ khái niệm giữa tập hợp và các phần tử của nó.

Các Thao tác trên Tài nguyên và Tập hợp

Tương tác với tài nguyên và tập hợp trong API REST được thực hiện thông qua các phương thức HTTP tiêu chuẩn. Các phương thức này xác định các hành động sẽ được thực hiện. Các phương thức phổ biến nhất là:

GET: Được sử dụng để truy xuất biểu diễn của một tài nguyên hoặc một tập hợp.

POST: Chủ yếu được sử dụng để tạo một tài nguyên mới trong một tập hợp. Phần thân yêu cầu (request body) thường chứa biểu diễn của tài nguyên mới sẽ được tạo.

PUT: Được sử dụng để cập nhật hoàn toàn một tài nguyên hiện có. Phần thân yêu cầu nên chứa toàn bộ biểu diễn mới của tài nguyên. Nếu tài nguyên được xác định bởi URI tồn tại, nó sẽ được thay thế bằng biểu diễn mới. Nếu nó không tồn tại, một số API có thể chọn tạo nó (mặc dù hành vi này có thể khác nhau).

DELETE: Được sử dụng để xóa một tài nguyên.

PATCH: Được sử dụng để cập nhật một phần tài nguyên hiện có. Không giống như PUT, yêu cầu client gửi toàn bộ biểu diễn của tài nguyên, PATCH cho phép chỉ gửi các thay đổi. Ví dụ, để chỉ cập nhật địa chỉ email của người dùng, yêu cầu PATCH chỉ cần bao gồm email mới.

Tài nguyên Đơn lẻ (Singleton Resources)

Trong khi các tập hợp và các thành viên của chúng rất phổ biến, đôi khi một tài nguyên là một thực thể độc lập, thường được gọi là tài nguyên "đơn lẻ" (singleton). Một ví dụ điển hình có thể là cấu hình của một ứng dụng cụ thể hoặc trạng thái hiện tại của một hệ thống.

Ví dụ, /application/configuration có thể là URI cho một tài nguyên đơn lẻ đại diện cho cài đặt cấu hình của ứng dụng. Một yêu cầu GET đến URI này sẽ truy xuất cấu hình hiện tại và một yêu cầu PUT có thể được sử dụng để cập nhật nó. Không có "tập hợp" các cấu hình trong ngữ cảnh này; chỉ có cấu hình đó.

Tương tự, /system/status có thể đại diện cho trạng thái hoạt động hiện tại của hệ thống.

Các Thực hành Tốt nhất để Thiết kế API dựa trên Tài nguyên

Thiết kế API lấy tài nguyên làm trung tâm bao gồm nhiều hơn việc chỉ xác định các thực thể và ánh xạ chúng tới URI. Một số thực hành tốt nhất góp phần tạo ra một API mạnh mẽ và thân thiện với người dùng:

  1. Sử dụng Danh từ cho URI: Như đã đề cập trước đó, URI tài nguyên nên là danh từ (ví dụ: /products, /users/{userId}/orders). Động từ nên được dành riêng cho các phương thức HTTP.
  2. Đặt tên URI nhất quán: Sử dụng quy ước đặt tên nhất quán cho các URI của bạn. Danh từ số nhiều thường được ưu tiên cho các tập hợp (ví dụ: /customers thay vì /customer). Sử dụng dấu gạch nối (-) để cải thiện khả năng đọc của các phân đoạn đường dẫn dài (ví dụ: /product-categories) thay vì dấu gạch dưới (_) hoặc camelCase.
  3. Giữ URI đơn giản và phân cấp: Thiết kế URI phản ánh mối quan hệ giữa các tài nguyên. Ví dụ, /users/{userId}/accounts/{accountId} cho thấy rõ ràng rằng một tài khoản thuộc về một người dùng. Tuy nhiên, tránh lồng ghép quá sâu, điều này có thể làm cho URI trở nên khó sử dụng.
  4. Không trạng thái (Statelessness): Mỗi yêu cầu từ client đến máy chủ phải chứa tất cả thông tin cần thiết để hiểu1 và xử lý yêu cầu. Máy chủ2 không nên lưu trữ bất kỳ ngữ cảnh client nào giữa các yêu cầu. Đây là nguyên tắc cốt lõi của REST và góp phần vào khả năng mở rộng.
  5. Tận dụng các phương thức HTTP một cách chính xác: Sử dụng GET, POST, PUT, DELETE và PATCH theo ngữ nghĩa đã định nghĩa của chúng. Không sử dụng GET để sửa đổi dữ liệu hoặc POST để truy xuất dữ liệu khi GET là phù hợp.
  6. Sử dụng mã trạng thái HTTP thích hợp: Trả về các mã trạng thái HTTP tiêu chuẩn để chỉ ra kết quả của yêu cầu (ví dụ: 200 OK, 201 Created, 204 No Content, 400 Bad Request, 401 Unauthorized, 403 Forbidden,3 404 Not Found, 500 Internal Server Error). Điều này cung cấp phản hồi rõ ràng cho client.
  7. Hỗ trợ đàm phán nội dung (Content Negotiation): Cho phép client chỉ định định dạng biểu diễn mong muốn (ví dụ: JSON, XML) bằng cách sử dụng tiêu đề Accept và chỉ định định dạng của phần thân yêu cầu bằng cách sử dụng tiêu đề Content-Type.
  8. Phiên bản hóa (Versioning): Lập kế hoạch cho sự phát triển của API bằng cách triển khai chiến lược phiên bản hóa (ví dụ: /v1/products). Điều này cho phép bạn giới thiệu các thay đổi gây phá vỡ mà không ảnh hưởng đến các client hiện có.
  9. Cung cấp biểu diễn lỗi có ý nghĩa: Khi xảy ra lỗi, trả về một thông báo lỗi hữu ích trong phần thân phản hồi (thường là JSON hoặc XML) giải thích điều gì đã xảy ra.
  10. Hypermedia là Động cơ của Trạng thái Ứng dụng (HATEOAS): Mặc dù không phải lúc nào cũng được triển khai đầy đủ, HATEOAS là một nguyên tắc chính của REST. Điều đó có nghĩa là các biểu diễn của tài nguyên nên bao gồm các liên kết (kiểm soát hypermedia) cho phép client khám phá các hành động và tài nguyên liên quan. Ví dụ, biểu diễn của một đơn hàng có thể bao gồm các liên kết để hủy đơn hàng, xem trạng thái vận chuyển của nó hoặc xem các sản phẩm mà nó chứa. Điều này làm cho API dễ tự khám phá hơn.

Độ chi tiết của Tài nguyên

Một thách thức thiết kế phổ biến là xác định độ chi tiết phù hợp cho các tài nguyên của bạn. Một địa chỉ có nên là một tài nguyên riêng biệt hay là một phần của tài nguyên người dùng? Các mục đơn hàng có nên là tài nguyên riêng biệt hay được nhúng trong tài nguyên đơn hàng?

Không có câu trả lời đúng duy nhất; nó phụ thuộc vào các trường hợp sử dụng cụ thể và cách client thường tương tác với dữ liệu.

Sự lựa chọn thường liên quan đến sự đánh đổi:

Cân nhắc cẩn thận các yếu tố này, cùng với sự hiểu biết sâu sắc về cách API sẽ được sử dụng, là rất quan trọng để đưa ra quyết định đúng đắn về độ chi tiết của tài nguyên.

💡
Bạn muốn một công cụ kiểm thử API tuyệt vời tạo ra Tài liệu API đẹp mắt?

Bạn muốn một nền tảng Tích hợp, Tất cả trong Một để Đội ngũ Phát triển của bạn làm việc cùng nhau với năng suất tối đa?

Apidog đáp ứng mọi nhu cầu của bạn và thay thế Postman với mức giá phải chăng hơn nhiều!
button

Kết luận

Tài nguyên là các khối xây dựng nền tảng của bất kỳ API RESTful nào. Chúng đại diện cho "những thứ" mà API hiển thị và cho phép client tương tác. Bằng cách gán URI duy nhất cho tài nguyên, phân biệt giữa tài nguyên và biểu diễn của nó, và tổ chức tài nguyên thành các tập hợp logic, các nhà phát triển có thể tạo ra các API trực quan, có khả năng mở rộng và tuân thủ các nguyên tắc của REST.

Hiểu cách định nghĩa, xác định và thao tác tài nguyên bằng cách sử dụng các phương thức HTTP tiêu chuẩn là điều cần thiết cho cả nhà thiết kế và người tiêu dùng API. Kết hợp với các thực hành tốt nhất trong thiết kế URI, sử dụng mã trạng thái HTTP thích hợp và cách tiếp cận chu đáo về độ chi tiết của tài nguyên, mô hình tài nguyên được xác định rõ ràng sẽ dẫn đến các API không chỉ hoạt động tốt mà còn dễ dàng làm việc cùng. Khi bối cảnh kỹ thuật số tiếp tục phát triển, các nguyên tắc của kiến trúc hướng tài nguyên sẽ vẫn là nền tảng của giao tiếp dịch vụ web hiệu quả.

Thực hành thiết kế API trong Apidog

Khám phá cách dễ dàng hơn để xây dựng và sử dụng API