Hiểu các ràng buộc REST của Roy Fielding và cách chúng định hình thiết kế API và web app: client–server, không trạng thái, cache, giao diện đồng nhất, hệ thống theo lớp, và hơn thế nữa.

Roy Fielding không chỉ là một cái tên gắn với buzzword API. Ông là một trong những tác giả chính của các đặc tả HTTP và URI và, trong luận án tiến sĩ của mình, mô tả một kiểu kiến trúc gọi là REST (Representational State Transfer) để giải thích tại sao Web hoạt động tốt như vậy.
Nguồn gốc đó quan trọng vì REST không được phát minh để tạo ra “endpoint trông đẹp.” Nó là cách mô tả các ràng buộc cho phép một mạng lưới toàn cầu, lộn xộn vẫn mở rộng được: nhiều client, nhiều server, các tầng trung gian, caching, lỗi từng phần và thay đổi liên tục.
Nếu bạn từng tự hỏi tại sao hai “REST API” lại cảm thấy hoàn toàn khác—hoặc tại sao một quyết định thiết kế nhỏ sau này trở thành cơn đau phân trang, nhầm lẫn về cache, hoặc phá vỡ tương thích—hướng dẫn này nhằm giảm những bất ngờ đó.
Bạn sẽ có được:
REST không phải là một checklist, một giao thức, hay một chứng nhận. Fielding mô tả nó như một kiểu kiến trúc: một tập các ràng buộc, khi áp dụng cùng nhau, tạo ra hệ thống mở rộng như Web—dễ dùng, có thể tiến hóa theo thời gian, và thân thiện với các trung gian (proxy, cache, gateway) mà không cần phối hợp liên tục.
Web sơ khai cần hoạt động giữa nhiều tổ chức, server, mạng và loại client khác nhau. Nó phải lớn lên mà không có điều khiển tập trung, sống sót qua lỗi từng phần, và cho phép tính năng mới xuất hiện mà không phá vỡ tính năng cũ. REST giải quyết điều đó bằng cách ưu tiên một số khái niệm được chia sẻ rộng rãi (như định danh, biểu diễn, và thao tác chuẩn) thay vì các hợp đồng tùy chỉnh, gắn chặt.
Một ràng buộc là một quy tắc giới hạn tự do thiết kế để đổi lấy lợi ích. Ví dụ, bạn có thể bỏ state phiên ở server để các request có thể được xử lý bởi bất kỳ node server nào, điều này cải thiện tính khả dụng và scale. Mỗi ràng buộc của REST thực hiện trao đổi tương tự: ít linh hoạt tùy ý hơn, nhiều dự đoán và khả năng tiến hóa hơn.
Nhiều API HTTP mượn ý tưởng REST (JSON qua HTTP, endpoint URL, có thể dùng mã trạng thái) nhưng không áp dụng đầy đủ các ràng buộc. Điều đó không hẳn là “sai”—thường phản ánh hạn chót sản phẩm hoặc nhu cầu chỉ dùng nội bộ. Tuy nhiên gọi rõ sự khác biệt là hữu ích: một API có thể hướng tài nguyên mà không hoàn chỉnh theo REST.
Hãy nghĩ một hệ thống REST là tập các tài nguyên (những thứ bạn có thể đánh dấu bằng URL) mà client tương tác qua biểu diễn (lượt xem hiện tại của tài nguyên, như JSON hoặc HTML), được hướng dẫn bởi liên kết (hành động tiếp theo và tài nguyên liên quan). Client không cần quy tắc bí mật ngoài băng thông; nó theo ngữ nghĩa chuẩn và duyệt theo liên kết, giống như trình duyệt di chuyển trên Web.
Trước khi lạc vào các ràng buộc và chi tiết HTTP, REST bắt đầu bằng một sự thay đổi từ vựng đơn giản: hãy nghĩ theo tài nguyên, không phải hành động.
Một tài nguyên là một “thứ” có địa chỉ trong hệ thống của bạn: một người dùng, một hóa đơn, một danh mục sản phẩm, một giỏ hàng. Quan trọng là đó là một danh từ có danh tính.
Đó là lý do /users/123 đọc tự nhiên: nó định danh người dùng có ID 123. So sánh với URL theo hành động như /getUser hoặc /updateUserPassword. Chúng mô tả động từ—thao tác—chứ không phải đối tượng bạn thao tác.
REST không nói bạn không thể thực hiện hành động. Nó nói hành động nên được biểu đạt qua giao diện đồng nhất (với API HTTP thường là phương thức GET/POST/PUT/PATCH/DELETE) tác động lên định danh tài nguyên.
Một biểu diễn là thứ bạn gửi qua đường truyền như một ảnh chụp hay cách nhìn của tài nguyên tại một thời điểm. Cùng một tài nguyên có thể có nhiều biểu diễn.
Ví dụ, tài nguyên /users/123 có thể được biểu diễn dưới dạng JSON cho ứng dụng, hoặc HTML cho trình duyệt.
GET /users/123
Accept: application/json
Có thể trả về:
{
"id": 123,
"name": "Asha",
"email": "[email protected]"
}
Trong khi:
GET /users/123
Accept: text/html
Có thể trả về một trang HTML hiển thị cùng thông tin người dùng.
Ý chính: tài nguyên không phải là JSON và cũng không phải là HTML. Chúng chỉ là định dạng dùng để biểu diễn nó.
Khi bạn mô hình API quanh tài nguyên và biểu diễn, vài quyết định thực tế trở nên dễ hơn:
/users/123 vẫn hợp lệ ngay cả khi UI, workflow, hoặc mô hình dữ liệu thay đổi.Tư duy ưu tiên tài nguyên này là nền tảng cho các ràng buộc REST. Không có nó, “REST” thường trở thành “JSON qua HTTP với vài pattern URL đẹp.”
Phân tách client–server là cách REST buộc tách nhiệm vụ rõ ràng. Client tập trung vào trải nghiệm người dùng (những gì người dùng thấy và làm), trong khi server tập trung vào dữ liệu, luật và lưu trữ (cái gì là đúng và được phép). Khi giữ các mối quan tâm tách biệt, mỗi bên có thể thay đổi mà không buộc phải viết lại bên kia.
Trong ngôn ngữ hàng ngày, client là “lớp trình bày”: màn hình, điều hướng, validate form để phản hồi nhanh, và UI lạc quan (như hiển thị bình luận mới ngay lập tức). Server là “nguồn chân thật”: xác thực, ủy quyền, luật nghiệp vụ, lưu trữ, auditing, và mọi thứ phải nhất quán giữa các thiết bị.
Một quy tắc thực tế: nếu quyết định ảnh hưởng đến bảo mật, tiền bạc, quyền hạn hoặc tính nhất quán chia sẻ, nó thuộc server. Nếu ảnh hưởng chỉ đến cảm nhận trải nghiệm (bố cục, gợi ý đầu vào cục bộ, trạng thái tải), nó thuộc client.
Ràng buộc này tương ứng trực tiếp với các thiết lập phổ biến:
Phân tách client–server là điều làm cho “một backend, nhiều frontend” trở nên thực tế.
Một lỗi phổ biến là lưu trạng thái luồng UI trên server (ví dụ: “người dùng đang ở bước checkout nào”) trong session phía server. Điều đó gắn backend vào một luồng màn hình cụ thể và làm scale khó hơn.
Ưu tiên gửi ngữ cảnh cần thiết cùng mỗi yêu cầu (hoặc suy ra từ tài nguyên đã lưu), để server tập trung vào tài nguyên và quy tắc—không phải nhớ client đang ở bước nào.
Không trạng thái nghĩa là server không cần nhớ gì về client giữa các yêu cầu. Mỗi yêu cầu mang toàn bộ thông tin cần để hiểu và phản hồi đúng—ai gọi, họ muốn gì, và bất kỳ ngữ cảnh nào cần để xử lý.
Khi các yêu cầu độc lập, bạn có thể thêm hoặc bớt server phía sau load balancer mà không lo “server nào biết session của tôi.” Điều đó cải thiện khả năng mở rộng và độ bền: bất kỳ instance nào cũng có thể xử lý bất kỳ yêu cầu nào.
Nó cũng đơn giản hóa vận hành. Debug thường dễ hơn vì toàn bộ ngữ cảnh hiển thị trong yêu cầu (và logs), thay vì bị ẩn trong bộ nhớ session server.
API không trạng thái thường gửi nhiều dữ liệu hơn mỗi lần gọi. Thay vì dựa vào session lưu ở server, client gửi credential và ngữ cảnh mỗi lần.
Bạn cũng phải rõ ràng về các luồng “có trạng thái” (như phân trang hoặc checkout nhiều bước). REST không cấm trải nghiệm nhiều bước—nó chỉ đẩy trạng thái về client hoặc tài nguyên phía server được định danh và truy xuất được.
Authorization: Bearer … để bất kỳ server nào cũng xác thực được.Idempotency-Key để retry không tạo trùng lặp.X-Correlation-Id cho phép truy vết một hành động người dùng qua các service và logs, ngay cả trong hệ phân tán.Với phân trang, tránh “server nhớ trang 3.” Ưu tiên tham số rõ ràng như ?cursor=abc hoặc một liên kết next mà client theo dõi, giữ trạng thái điều hướng trong phản hồi thay vì trong bộ nhớ server.
Caching là tái sử dụng phản hồi trước đó một cách an toàn để client (hoặc thứ gì đó ở giữa) không phải hỏi server của bạn để làm cùng một công việc nữa. Làm tốt, nó giảm độ trễ cho người dùng và giảm tải cho bạn—mà không thay đổi nghĩa của API.
Một phản hồi có thể cache khi an toàn để một yêu cầu khác nhận cùng payload đó trong một khoảng thời gian. Trong HTTP, bạn truyền đạt ý định đó bằng header cache:
Cache-Control: bộ điều khiển chính (bao lâu giữ, có thể lưu ở cache chia sẻ hay không, v.v.)ETag và Last-Modified: bộ xác thực cho phép client hỏi “đã thay đổi chưa?” và nhận trả lời rẻ tiền “không thay đổi”Expires: cách cũ hơn để biểu thị độ tươi, vẫn thấy ở thực tếĐiều này lớn hơn “cache trình duyệt.” Proxy, CDN, API gateway, và thậm chí ứng dụng mobile có thể tái sử dụng phản hồi khi quy tắc rõ ràng.
Ứng viên tốt:
Thường không nên cache:
private)Ý chính: caching không phải chuyện phụ. Đó là một ràng buộc REST thưởng cho API truyền rõ ràng độ tươi và xác thực.
Giao diện đồng nhất thường bị hiểu nhầm là “dùng GET để đọc và POST để tạo.” Đó chỉ là một phần nhỏ. Ý tưởng của Fielding lớn hơn: API nên cảm thấy nhất quán đến mức client không cần kiến thức đặc thù từng endpoint để dùng chúng.
Định danh tài nguyên: Bạn đặt tên đồ vật (tài nguyên) bằng định danh ổn định (thường là URL), không phải hành động. Nghĩ /orders/123, không phải /createOrder.
Thao tác qua biểu diễn: Client thay đổi tài nguyên bằng cách gửi một biểu diễn (JSON, HTML, v.v.). Server kiểm soát tài nguyên; client trao đổi các biểu diễn của nó.
Thông điệp tự mô tả: Mỗi yêu cầu/phản hồi nên mang đủ thông tin để hiểu cách xử lý—phương thức, mã trạng thái, header, media type, và body rõ ràng. Nếu ý nghĩa ẩn trong docs ngoài băng thông, client sẽ phụ thuộc chặt.
Hypermedia (HATEOAS): Phản hồi nên bao gồm liên kết và hành động cho phép để client theo workflow mà không mã hóa cứng mọi mẫu URL.
Một giao diện nhất quán làm client ít phụ thuộc vào chi tiết nội bộ server. Qua thời gian, điều đó nghĩa là ít thay đổi phá vỡ, ít “trường hợp đặc biệt,” và ít phải làm lại khi nhóm thay đổi endpoint.
200 cho đọc thành công, 201 cho tạo (kèm Location), 400 cho validation, 401/403 cho auth, 404 khi tài nguyên không tồn tại.code, message, details, requestId.Content-Type, header cache), để thông điệp tự giải thích.Giao diện đồng nhất nói về tính dự đoán và khả năng tiến hóa, không chỉ “dùng đúng động từ.”
Một thông điệp “tự mô tả” là thông điệp cho người nhận biết cách diễn giải nó—không cần kiến thức riêng bên ngoài. Nếu một client (hoặc trung gian) không thể hiểu phản hồi nghĩa là gì chỉ bằng cách nhìn header HTTP và body, bạn đã tạo ra một giao thức riêng chạy trên HTTP.
Chiến thắng đơn giản nhất là rõ ràng với Content-Type (bạn đang gửi gì) và thường Accept (bạn muốn nhận gì). Phản hồi Content-Type: application/json nói cho client biết cách parse cơ bản, nhưng bạn có thể đi xa hơn với media type vendor hoặc profile khi ý nghĩa quan trọng.
Các cách tiếp cận:
application/json với schema được duy trì. Dễ nhất cho hầu hết nhóm.application/vnd.acme.invoice+json để báo hiệu biểu diễn cụ thể.application/json, thêm tham số profile hoặc liên kết đến profile định nghĩa ngữ nghĩa.Versioning nên bảo vệ client hiện có. Các lựa chọn phổ biến gồm:
/v1/orders): rõ ràng, nhưng có thể khuyến khích “fork” biểu diễn thay vì tiến hóa.Accept): giữ URL ổn định và làm “ý nghĩa” thành một phần của thông điệp.Dù chọn gì, hướng về tương thích ngược theo mặc định: đừng đổi tên trường bừa bãi, đừng thay đổi ý nghĩa âm thầm, và coi việc loại bỏ là thay đổi phá vỡ.
Client học nhanh khi lỗi cùng hình dạng ở mọi nơi. Chọn một kiểu lỗi (ví dụ code, message, details, traceId) và dùng khắp các endpoint. Dùng tên trường rõ ràng (createdAt vs created_at) và giữ một quy ước duy nhất.
Tài liệu tốt giúp nhanh chóng áp dụng, nhưng không thể là nơi duy nhất chứa ý nghĩa. Nếu client phải đọc wiki để biết status: 2 là “paid” hay “pending”, thông điệp đó không tự mô tả. Header, media type và payload rõ ràng giảm sự phụ thuộc này và làm hệ thống dễ tiến hóa hơn.
Hypermedia (tóm tắt là HATEOAS: Hypermedia As The Engine Of Application State) nghĩa là client không cần “biết” trước URL tiếp theo của API. Thay vào đó, mỗi phản hồi bao gồm các bước tiếp theo có thể khám phá dưới dạng liên kết: nơi đi tiếp, hành động khả dụng, và đôi khi là phương thức HTTP cần dùng.
Thay vì mã hóa cứng đường dẫn như /orders/{id}/cancel, client theo các liên kết do server cung cấp. Server nói: “Dựa trên trạng thái hiện tại của tài nguyên này, đây là các bước hợp lệ.”
{
"id": "ord_123",
"status": "pending",
"total": 49.90,
"_links": {
"self": { "href": "/orders/ord_123" },
"payment":{ "href": "/orders/ord_123/payment", "method": "POST" },
"cancel": { "href": "/orders/ord_123", "method": "DELETE" }
}
}
Nếu đơn hàng sau đó trở thành paid, server có thể ngưng gửi cancel và thêm refund—mà không phá vỡ client tuân thủ đúng hành vi.
Hypermedia tỏa sáng khi luồng thay đổi: onboarding, checkout, phê duyệt, đăng ký, hoặc bất kỳ quy trình nào “hành động tiếp theo hợp lệ” thay đổi theo trạng thái, quyền, hoặc luật nghiệp vụ.
Nó cũng giảm URL mã hóa cứng và các giả định dễ vỡ của client. Bạn có thể tái tổ chức route, thêm hành động mới, hoặc khai tử hành động cũ trong khi client vẫn hoạt động miễn là bạn giữ nguyên ý nghĩa quan hệ liên kết.
Đội thường bỏ qua HATEOAS vì nó có vẻ tăng công việc: định nghĩa định dạng liên kết, thống nhất tên quan hệ, và dạy lập trình viên client theo liên kết thay vì xây URL.
Điều bạn mất là một lợi ích quan trọng của REST: giảm ràng buộc chặt. Không có hypermedia, nhiều API biến thành “RPC qua HTTP”—chúng dùng HTTP, nhưng client vẫn phụ thuộc nhiều vào tài liệu ngoài băng thông và mẫu URL cố định.
Hệ thống theo lớp nghĩa là client không cần biết (và thường không thể biết) nó đang nói chuyện với server gốc hay với các trung gian trên đường. Những lớp đó có thể là API gateway, reverse proxy, CDN, dịch vụ xác thực, WAF, service mesh, và cả định tuyến nội bộ giữa microservice.
Các lớp tạo ranh giới rõ ràng. Nhóm bảo mật có thể ép TLS, rate limit, xác thực và validate yêu cầu ở edge mà không thay đổi mọi service backend. Nhóm vận hành có thể scale theo chiều ngang sau gateway, thêm caching ở CDN, hoặc chuyển traffic trong sự cố. Với client, nó đơn giản hơn: một endpoint API ổn định, header nhất quán và định dạng lỗi dự đoán.
Trung gian có thể thêm độ trễ ẩn (nhiều hop, handshake thêm) và làm debug khó hơn: lỗi có thể nằm ở rule gateway, cache CDN, hoặc code origin. Caching cũng có thể gây nhầm lẫn khi các lớp khác nhau cache khác nhau, hoặc gateway sửa header làm ảnh hưởng khóa cache.
Các lớp rất mạnh—khi hệ thống vẫn quan sát được và dự đoán được.
Code-on-demand là ràng buộc REST duy nhất tùy chọn. Nó nghĩa là server có thể mở rộng client bằng cách gửi mã thực thi chạy trên client. Thay vì đóng gói mọi hành vi trong client trước, client có thể tải logic mới khi cần.
Nếu bạn đã từng tải trang web rồi nó trở nên tương tác—validate form, vẽ biểu đồ, lọc bảng—bạn đã dùng code-on-demand. Server gửi HTML và dữ liệu, cộng thêm JavaScript chạy trên trình duyệt để cung cấp hành vi.
Đây là lý do lớn khiến web tiến hóa nhanh: trình duyệt là client đa dụng, trong khi site phân phối chức năng mới mà không bắt người dùng cài app mới.
REST vẫn “hoạt động” mà không có code-on-demand vì các ràng buộc khác đã đủ để cho khả năng mở rộng, đơn giản và tương tác. Một API có thể chỉ phục vụ biểu diễn như JSON—client tự cài hành vi của mình.
Nhiều API hiện đại tránh gửi mã thực thi vì nó làm phức tạp:
Code-on-demand hữu ích khi bạn kiểm soát môi trường client và cần triển khai UI nhanh, hoặc muốn client mỏng tải “plugin” hay quy tắc từ server. Nhưng nên coi đó như công cụ thêm, không phải bắt buộc.
Kết luận chính: bạn có thể tuân thủ REST hoàn toàn mà không dùng code-on-demand—và nhiều API production vẫn làm vậy—vì ràng buộc này chỉ về khả năng mở rộng tùy chọn, không phải nền tảng tương tác hướng tài nguyên.
Hầu hết đội không từ chối REST—họ áp dụng phong cách “REST-ish” giữ HTTP như truyền tải trong khi lặng lẽ bỏ một số ràng buộc then chốt. Điều đó có thể ổn, miễn là đó là đánh đổi có ý thức chứ không phải tai nạn dẫn đến client dễ vỡ và phải viết lại tốn kém.
Một vài pattern lặp lại:
/doThing, /runReport, /users/activate—dễ đặt tên, dễ nối./createOrder, /updateProfile, /deleteItem—HTTP method chỉ là phụ.Những lựa chọn này thường hữu dụng lúc đầu vì phản ánh tên hàm nội bộ và vận hành.
Dùng đây làm review “chúng ta REST đến đâu, thực sự?”
/orders/{id} hơn /createOrder.Cache-Control, ETag, và Vary cho phản hồi GET.Ràng buộc REST không chỉ là lý thuyết—chúng là các hàng rào bạn cảm nhận khi triển khai. Khi bạn nhanh chóng tạo API (ví dụ scaffold frontend React với backend Go + PostgreSQL), sai lầm dễ nhất là để “cái gì nhanh nhất để nối” quyết định giao diện.
Nếu bạn dùng nền tảng vibe-coding như Koder.ai để xây web app từ chat, hãy đưa các ràng buộc REST vào cuộc nói chuyện sớm—đặt tên tài nguyên trước, giữ không trạng thái, định nghĩa hình dạng lỗi nhất quán, và quyết nơi cache an toàn. Bằng cách đó, dù lặp nhanh vẫn tạo API dự đoán được cho client và dễ tiến hóa. (Và vì Koder.ai hỗ trợ xuất mã nguồn, bạn có thể tiếp tục tinh chỉnh hợp đồng API và triển khai khi yêu cầu phát triển.)
Xác định tài nguyên chính trước, rồi chọn ràng buộc một cách có ý thức: nếu bạn bỏ qua caching hay hypermedia, ghi rõ vì sao và dùng gì thay thế. Mục tiêu không phải là thuần túy—mà là rõ ràng: định danh tài nguyên ổn định, ngữ nghĩa dự đoán, và các đánh đổi rõ ràng giúp client bền vững khi hệ thống tiến hóa.
REST (Representational State Transfer) là một kiểu kiến trúc Roy Fielding mô tả để giải thích lý do Web có thể mở rộng.
Nó không phải là một giao thức hay chứng nhận—mà là một tập hợp các ràng buộc (client–server, không trạng thái, có thể cache, giao diện đồng nhất, hệ thống theo lớp, và code-on-demand tùy chọn) đổi một số tính linh hoạt lấy khả năng mở rộng, khả năng tiến hóa và tương tác xuyên hệ thống.
Bởi vì nhiều API chỉ mượn một vài ý tưởng REST (JSON qua HTTP, URL rõ ràng) mà bỏ qua những ràng buộc khác (quy tắc cache hoặc hypermedia).
Hai API gọi là “REST” có thể khác nhau nhiều tùy thuộc vào việc chúng có:
Một tài nguyên là một danh từ bạn có thể định danh (ví dụ: /users/123). Một endpoint hành động là một động từ được nhúng trong URL (ví dụ: /getUser, /updatePassword).
Thiết kế theo hướng tài nguyên thường bền vững hơn vì định danh giữ ổn định khi giao diện người dùng và quy trình thay đổi. Hành động vẫn có thể tồn tại, nhưng thường được diễn đạt qua phương thức HTTP và biểu diễn thay vì đường dẫn dạng động từ.
Tài nguyên là khái niệm (ví dụ: “user 123”). Biểu diễn là ảnh chụp bạn truyền đi (JSON, HTML, v.v.).
Điều này quan trọng vì bạn có thể thay đổi hoặc thêm biểu diễn mà không đổi định danh tài nguyên. Client nên phụ thuộc vào ý nghĩa tài nguyên hơn là một định dạng payload duy nhất.
Phân tách client–server giữ trách nhiệm rõ ràng:
Nếu quyết định ảnh hưởng đến bảo mật, tiền bạc, quyền hạn hoặc tính nhất quán chia sẻ, nó thuộc về server. Sự tách biệt này cho phép “một backend, nhiều frontend” (web, mobile, đối tác).
Không trạng thái nghĩa là server không dựa vào session lưu trên máy chủ để hiểu một yêu cầu. Mỗi yêu cầu bao gồm những gì cần thiết (xác thực + ngữ cảnh).
Lợi ích gồm dễ scale theo chiều ngang (bất kỳ node nào cũng xử lý được yêu cầu) và debug đơn giản hơn (ngữ cảnh hiện trong logs).
Các pattern phổ biến:
Authorization: Bearer … trên mọi lần gọiCác phản hồi có thể cache cho phép client và các trung gian tái sử dụng nội dung an toàn, giảm độ trễ và tải server.
Công cụ HTTP thực tế:
Cache-Control cho độ tươi và phạm viGiao diện đồng nhất không chỉ là “dùng đúng GET/POST/PUT/DELETE.” Mấu chốt là API phải đủ nhất quán để client không cần kiến thức đặc thù từng endpoint.
Trong thực tế, tập trung vào:
Hypermedia nghĩa là phản hồi bao gồm các liên kết đến hành động tiếp theo hợp lệ, nên client theo liên kết thay vì ép xâu mẫu URL.
Nó hữu ích nhất khi luồng thay đổi theo trạng thái hoặc quyền (checkout, phê duyệt, onboarding). Client có thể bền bỉ nếu server thêm/bớt hành động bằng cách thay đổi tập liên kết.
Nhiều đội bỏ qua vì cần thêm công việc thiết kế (định dạng liên kết, tên quan hệ), nhưng đánh đổi là giảm ràng buộc chặt chẽ vào tài liệu và URL cố định.
Hệ thống theo lớp cho phép có các trung gian (CDN, gateway, proxy, lớp auth) nên client không cần biết thành phần nào thực sự phục vụ phản hồi.
Để tránh lớp trung gian trở thành cơn đau đầu khi debug:
500 chung chung)Lớp là lợi thế khi hệ thống vẫn có khả năng quan sát và dự đoán được.
?cursor=... hoặc link next) thay vì “server nhớ trang 3”ETagLast-Modified304 Not ModifiedVary khi phản hồi thay đổi theo header như AcceptQuy tắc đơn giản: cache dữ liệu công cộng, giống nhau cho mọi người; xử lý dữ liệu người dùng cẩn trọng (thường private hoặc không cache).
200, 201 + Location, 400, 401/403, 404)code, message, details, requestId)Những điều này giảm ràng buộc và làm thay đổi ít có khả năng phá vỡ client.