NỘI DUNG BÀI HỌC
✅ Hiểu bản chất HTTP Status Code
✅ Phân loại và sử dụng đúng status code trong từng tình huống
✅ Phân biệt rõ PUT vs PATCH
✅ Phân biệt chính xác 401 vs 403
✅ Áp dụng status code vào kiểm tra kết quả API một cách nhất quán
✅ Đọc response và đánh giá đúng hành vi hệ thống
🌐 I. HTTP STATUS CODE – KHÁI NIỆM & PHÂN LOẠI
📌 Khái niệm
HTTP Status Code là mã phản hồi do server trả về để mô tả kết quả xử lý của request tại tầng HTTP.
Status code giúp:
-
Xác định request thành công hay thất bại
-
Xác định lỗi thuộc client hay server
-
Định hướng hành động tiếp theo của client
🗂️ Phân nhóm Status Code
| Nhóm | Ý nghĩa | Mô tả |
|---|---|---|
| 🟢 2xx | Success | Xử lý thành công |
| 🟡 4xx | Client Error | Request không hợp lệ |
| 🔴 5xx | Server Error | Lỗi hệ thống |
🟢 II. NHÓM 2xx – SUCCESS RESPONSES
🟢 200 – OK
🔍 Khái niệm
-
Server đã nhận request hợp lệ
-
Request được xử lý thành công
-
Response được trả về đúng định dạng
⚠️ Lưu ý:
Status 200 chỉ phản ánh thành công ở tầng HTTP, không đảm bảo business logic luôn đúng.
📍 Trường hợp áp dụng
-
GET lấy dữ liệu
-
PUT cập nhật toàn bộ
-
PATCH cập nhật một phần
-
Một số API dùng 200 cho POST
🚫 Không nên dùng khi
-
Tạo mới tài nguyên (nên dùng 201)
-
Business thất bại nhưng vẫn trả 200
➕ Ưu điểm
-
Phổ biến, dễ hiểu
-
Tương thích tốt với client
➖ Nhược điểm
-
Dễ bị lạm dụng
-
Có thể che giấu lỗi nghiệp vụ
💻 Ví dụ
res = api_context.get("/posts/1")
assert res.status == 200
🟢 201 – Created
🔍 Khái niệm
-
Server tạo mới tài nguyên thành công
-
Thường trả về dữ liệu hoặc ID của tài nguyên mới
📍 Trường hợp áp dụng
-
POST tạo user
-
POST tạo article / order / record
🚫 Không nên dùng khi
-
Update tài nguyên đã tồn tại
-
Không tạo mới dữ liệu
➕ Ưu điểm
-
Phân biệt rõ create vs update
-
Client biết chắc resource đã được tạo
➖ Nhược điểm
-
Không phải hệ thống nào cũng tuân thủ chuẩn
💻 Ví dụ
res = api_context.post("/posts", data=payload)
assert res.status in (200, 201)
🟡 III. NHÓM 4xx – CLIENT ERROR RESPONSES
🟡 400 – Bad Request
🔍 Khái niệm
Request không hợp lệ do:
-
Sai schema
-
Thiếu field bắt buộc
-
Sai datatype
-
Vi phạm validation rule
📍 Trường hợp áp dụng
-
Payload thiếu required field
-
Dữ liệu không đúng format
-
Giá trị không hợp lệ
🚫 Không nên dùng khi
-
Lỗi xác thực → 401
-
Lỗi phân quyền → 403
-
Lỗi hệ thống → 500
➕ Ưu điểm
-
Xác định rõ lỗi nằm ở request
-
Phù hợp cho negative testing
➖ Nhược điểm
-
Message không rõ gây khó debug
-
Dễ gom nhiều lỗi khác nhau
💻 Ví dụ
res = api_context.post("/posts", data={})
assert res.status == 400
🟡 401 – Unauthorized
🔍 Khái niệm
Request chưa được xác thực, server không xác định được danh tính client.
📍 Trường hợp áp dụng
-
Không gửi token
-
Token sai
-
Token hết hạn
🚫 Không nên dùng khi
-
Token hợp lệ nhưng không đủ quyền (nên dùng 403)
➕ Ưu điểm
-
Rõ ràng về xác thực
-
Client biết cần login lại
➖ Nhược điểm
-
Dễ nhầm với 403
💻 Ví dụ
res = api_context.get("/secure-data")
assert res.status == 401
🟡 403 – Forbidden
🔍 Khái niệm
Request đã được xác thực nhưng không có quyền truy cập tài nguyên.
📍 Trường hợp áp dụng
-
Role không đủ quyền
-
Permission bị hạn chế
-
Truy cập tài nguyên đặc biệt
🚫 Không nên dùng khi
-
Chưa xác thực (nên dùng 401)
➕ Ưu điểm
-
Phù hợp mô hình RBAC / ACL
-
Rõ ràng về bảo mật
➖ Nhược điểm
-
Client không thể tự xử lý tiếp
💻 Ví dụ
res = api_context.get("/admin")
assert res.status == 403
🟡 404 – Not Found
🔍 Khái niệm
Tài nguyên hoặc endpoint không tồn tại.
📍 Trường hợp áp dụng
-
ID không tồn tại
-
URL sai
🚫 Không nên dùng khi
-
Không có quyền truy cập (nên dùng 403)
🔴 IV. NHÓM 5xx – SERVER ERROR RESPONSES
🔴 500 – Internal Server Error
🔍 Khái niệm
Server gặp lỗi trong quá trình xử lý request và không thể hoàn thành.
📍 Trường hợp áp dụng
-
Exception chưa được handle
-
Backend crash
-
Lỗi database
-
Lỗi logic server
🚫 Không nên dùng khi
-
Lỗi request từ client
-
Validation fail
➕ Ưu điểm
-
Dễ nhận biết lỗi hệ thống nghiêm trọng
➖ Nhược điểm
-
Thiếu thông tin debug nếu message không rõ
💻 Ví dụ
🔁 V. PUT vs PATCH – CHIẾN LƯỢC UPDATE
🔄 PUT – Update toàn bộ tài nguyên
-
Gửi đầy đủ object
-
Field không gửi có thể bị overwrite
-
Dùng khi cần thay thế hoàn toàn
✏️ PATCH – Update một phần tài nguyên
-
Chỉ gửi field cần cập nhật
-
Field khác giữ nguyên
-
An toàn hơn PUT
📊 So sánh PUT và PATCH
| Tiêu chí | PUT | PATCH |
|---|---|---|
| Mục đích | Thay thế | Chỉnh sửa |
| Payload | Đầy đủ | Một phần |
| Nguy cơ mất data | Cao | Thấp |
| Trường hợp dùng | Replace | Edit |
🔐 VI. PHÂN BIỆT 401 & 403
| Status | Ý nghĩa |
|---|---|
| 401 | Chưa xác thực |
| 403 | Đã xác thực nhưng không có quyền |
🧾 VII. TỔNG KẾT KIẾN THỨC
-
HTTP Status Code phản ánh kết quả xử lý request ở tầng HTTP
-
2xx: thành công
-
4xx: lỗi phía client
-
5xx: lỗi phía server
-
PUT và PATCH phục vụ các chiến lược update khác nhau
401 và 403 khác nhau về xác thực và phân quyền
VIII. NEGATIVE TESTING & ERROR HANDLING (CHÈN TRƯỚC)
1️⃣ Negative Testing là gì?
Negative Testing là kiểm tra hệ thống khi:
-
Input sai
-
Thiếu dữ liệu
-
Truy cập không hợp lệ
-
Vi phạm rule
Mục tiêu:
-
Đảm bảo hệ thống xử lý lỗi đúng cách
-
Trả status code phù hợp
-
Trả message rõ ràng
2️⃣ Các nhóm Negative Test phổ biến cho API
❌ Schema / Payload
-
Thiếu field required
-
Sai datatype
-
Field rỗng
→ Expect: 400
❌ Authentication
-
Không token
-
Token sai
-
Token hết hạn
→ Expect: 401
❌ Authorization
-
Role không đủ quyền
-
Truy cập API bị giới hạn
→ Expect: 403
❌ Resource
-
ID không tồn tại
-
URL sai
→ Expect: 404
❌ Server
-
Request hợp lệ nhưng server crash
→ Expect: 500
3️⃣ Error Handling – Nguyên tắc chung
Response lỗi nên có:
-
Status code đúng
-
Message rõ ràng
-
Error code (nếu có)
