Idempotency-Key
Idempotency-Key cho phép bạn gọi lại một request tạo mới mà không sợ tạo trùng, ví dụ khi mất kết nối giữa chừng và không biết lượt trước đã thành công hay chưa.
Header tuỳ chọn, hỗ trợ ở ba đường:
POST /orders(tạo đơn);POST /customers(tạo khách);POST /conversations/:id/messages(gửi tin nhắn).
curl -X POST "https://danix.vn/api/open/v1/customers" \
-H "Authorization: Bearer dnx_live_…" \
-H "Idempotency-Key: a3f9d1c2-7b4e-4c6a-8d21-5e0f9b8c7a64" \
-H "Content-Type: application/json" \
-d @customer.json
Dùng một chuỗi ngẫu nhiên khó đoán, thường là UUID v4, và sinh một lần cho mỗi ý định (một đơn bạn muốn tạo), rồi dùng lại chính nó khi thử lại ý định ấy.
Hành vi
| Tình huống | Kết quả |
|---|---|
| Lần đầu thấy khoá | Thực hiện bình thường và lưu kết quả. |
| Gửi lại cùng khoá, cùng thân, lượt trước đã xong | Phát lại đúng phản hồi đã lưu, kèm header Idempotent-Replayed: true; không tạo thêm gì. |
| Gửi lại cùng khoá khi lượt trước còn đang chạy | 409 idempotency-key-in-progress ngay lập tức, kèm Retry-After: 1. Không chờ. Gửi lại y nguyên sau một giây. |
| Cùng khoá nhưng thân khác | 422 idempotency-key-reused. Dùng khoá mới cho nội dung mới. |
Thời hạn và phạm vi
- Khoá được giữ 24 giờ. Sau đó, dùng lại cùng chuỗi được coi là một khoá mới và thực hiện lượt mới.
- Khoá có phạm vi theo ứng dụng kết nối: hai ứng dụng khác nhau dùng cùng một chuỗi không đụng nhau.
- Kết quả được ghi cùng giao dịch với lượt tạo, nên không có trường hợp tạo xong mà khoá chưa ghi.
- Chỉ lượt thành công được giữ. Lượt bị từ chối (ví dụ 400, 422 thiếu tồn kho) huỷ cả giao dịch lẫn khoá, nên gửi lại cùng khoá sau khi sửa nguyên nhân là chạy lại thật — với cùng thân thì kết quả có thể khác lần trước.
Với gửi tin nhắn
Gửi tin dùng cơ chế chống trùng sẵn có của chat: DANIX suy ra mã tin nhắn từ shop, ứng dụng, hội thoại và Idempotency-Key, nên thử lại cùng khoá trong cùng hội thoại không gửi tin hai lần tới khách. Những điểm khác với tạo đơn và tạo khách:
- Phạm vi là một hội thoại: cùng khoá gửi vào hai hội thoại khác nhau là hai tin, không phải lỗi
idempotency-key-reused. - Gửi lại cùng khoá trả trạng thái hiện tại của tin (ví dụ lần đầu
pending, lần sau đãsent), không phải nguyên văn phản hồi lần đầu. Ngoại lệ: khi shop gửi tin qua hàng đợi, một tinpendingmà hàng đợi bỏ cuộc không chuyển sangfailed— nó biến khỏiGET /conversations/{id}/messagessau khoảng 5 phút. Đừng dựa vào trạng thái tin để biết lượt gửi qua hàng đợi đã hỏng. - Kênh lỗi tạm thời (Facebook giới hạn tốc độ gọi của trang, máy chủ của kênh lỗi) trả 503
channel-unavailable: thử lại với cùng khoá và cùng thân là một lượt gửi mới, không phát lại lượt hỏng. Kênh từ chối vĩnh viễn trả 201 vớistatuslàfailed, và kết quả ấy được phát lại cho cùng khoá trong 24 giờ — muốn gửi lại thì dùng khoá mới.
Sau 24 giờ, cùng một khoá ra mã tin mới và tin được gửi như một tin mới.
Khuyến nghị
- Luôn gửi
Idempotency-Keykhi tạo đơn, tạo khách và gửi tin từ hệ thống tự động. - Khi gặp lỗi mạng, hết giờ hoặc 5xx, thử lại với cùng khoá. Khi gặp 4xx khác 409, sửa request thay vì thử lại.