REST là gì?
REST (Representational State Transfer) là một phong cách kiến trúc, không phải giao thức. Nó định nghĩa một tập các ràng buộc về cách các web service nên hoạt động. Khi một API tuân theo các ràng buộc này, ta gọi nó là RESTful. Ý tưởng cốt lõi rất đơn giản: client gửi một request đến một URL đại diện cho một resource, và server phản hồi bằng một representation của resource đó — thường là JSON.
Sáu ràng buộc định nghĩa REST gồm: phân tách client-server, stateless, khả năng cache, giao diện thống nhất, hệ thống phân lớp, và code on demand (tùy chọn). Trong thực tế, các ràng buộc quan trọng nhất hằng ngày là stateless và giao diện thống nhất. Stateless nghĩa là mỗi request phải chứa toàn bộ thông tin cần thiết để xử lý — server không lưu trạng thái phiên giữa các request. Giao diện thống nhất nghĩa là sử dụng các phương thức HTTP chuẩn và các mẫu URL dễ dự đoán.
Các phương thức HTTP và ý nghĩa
Phương thức HTTP cho server biết cần thực hiện hành động gì trên một resource. Mỗi phương thức mang một ngữ nghĩa cụ thể mà bạn cần tôn trọng — bỏ qua điều này sẽ dẫn đến các API khó hiểu và khó sử dụng.
GET dùng để lấy một resource mà không gây ra tác dụng phụ. POST dùng để tạo một resource mới. PUT dùng để thay thế toàn bộ một resource đã tồn tại. PATCH dùng để cập nhật một phần resource. DELETE dùng để xóa một resource.
Dưới đây là cách các phương thức này ánh xạ vào một resource users điển hình:
GET và DELETE là idempotent — gọi nhiều lần cho cùng kết quả. PUT cũng là idempotent. POST thì không — gọi POST hai lần thường tạo ra hai resource.
Mã trạng thái HTTP
Mã trạng thái cho client biết chuyện gì đã xảy ra. Chúng được chia thành năm nhóm: 1xx thông tin, 2xx thành công, 3xx chuyển hướng, 4xx lỗi client, 5xx lỗi server. Những mã bạn sẽ sử dụng thường xuyên nhất trong phát triển API là:
200 OK — yêu cầu thành công và có response body. Dùng mã này cho các phản hồi GET và PATCH thành công.
201 Created — một tài nguyên đã được tạo thành công. Dùng mã này sau khi POST thành công. Kèm theo header Location trỏ đến tài nguyên mới.
204 No Content — thành công, nhưng không có body để trả về. Dùng mã này cho DELETE.
400 Bad Request — client gửi dữ liệu không hợp lệ (thiếu trường, sai kiểu dữ liệu, lỗi validation).
401 Unauthorized — yêu cầu thiếu thông tin xác thực hợp lệ.
403 Forbidden — client đã xác thực nhưng không có quyền truy cập.
404 Not Found — tài nguyên không tồn tại.
409 Conflict — yêu cầu xung đột với trạng thái hiện tại (ví dụ: tạo người dùng với email đã tồn tại).
422 Unprocessable Entity — yêu cầu có cú pháp đúng nhưng không thỏa mãn validation ngữ nghĩa.
500 Internal Server Error — có lỗi xảy ra phía server. Không bao giờ để lộ stack trace ở đây trong môi trường production.
Một ví dụ cụ thể trong một handler của Express:
HTTP Headers trong ngữ cảnh API
Headers chứa metadata về request hoặc response. Có một vài header thiết yếu cho REST API.
Content-Type khai báo định dạng của body request hoặc response. Đối với JSON API, giá trị này luôn là application/json. Express sẽ tự động thiết lập khi bạn gọi res.json(), nhưng khi xây dựng response thô, bạn phải thiết lập một cách tường minh.
Accept cho server biết định dạng mà client có thể xử lý. Client nên gửi Accept: application/json khi gọi một JSON API.
Authorization mang theo thông tin xác thực. Mẫu phổ biến nhất cho REST API là xác thực bằng Bearer token:
Cache-Control chỉ định hành vi caching cho các response của GET. Với dữ liệu công khai ít khi thay đổi, việc đặt Cache-Control: public, max-age=300 giúp giảm tải cho server. Với dữ liệu riêng của người dùng hoặc dữ liệu nhạy cảm, hãy dùng Cache-Control: no-store.
Trong Express, bạn có thể đọc các header đến qua req.headers và thiết lập header đi qua res.set():
Tóm tắt
REST là một kiểu kiến trúc được xây dựng trên nền tảng giao tiếp client-server stateless với một giao diện thống nhất. Các phương thức HTTP định nghĩa hành động cần thực hiện trên một tài nguyên — GET để đọc, POST để tạo, PUT để thay thế, PATCH để cập nhật, DELETE để xóa. Mã trạng thái truyền tải chính xác kết quả: 2xx cho thành công, 4xx cho lỗi phía client, 5xx cho lỗi phía server. Headers chứa metadata như kiểu nội dung, thông tin xác thực và chỉ thị cache. Nắm vững các nguyên lý nền tảng này chính là điều phân biệt một API dễ tích hợp với một API buộc người dùng phải đoán.
Bài kiểm tra cuối bài