Bỏ qua để đến nội dung

Idempotency & thử lại

Mọi lệnh gọi thời gian thực phải mang Idempotency-Key. Đây không phải phép lịch sự về giới hạn tần suất — nó là thứ khiến việc thử lại an toàn. Mạng có thể hỏng sau khi nhà cung cấp đã được hỏi; không có key, cách duy nhất để biết một lần kiểm tra đã chạy hay chưa là chạy lại và trả tiền hai lần.

Hãy gửi một giá trị bạn có thể tạo lại: UUID, ID đơn hàng, hoặc hash của công việc bạn đang làm. Server giới hạn key theo tài khoản của bạn, nên hai người dùng không thể trùng nhau.

Cùng keyPayloadKết quả
Key mớibất kỳChạy bình thường, bị tính phí
Cùng keygiống hệtPhản hồi đã lưu được trả về; replayed=true. Không thu thêm phí.
Cùng keykhác409 idempotency_conflict — một key bị ràng buộc với payload mà nó mang lần đầu
Cùng keygiống hệt, lệnh gọi đầu vẫn đang chạy409 request_in_progress kèm Retry-After

Idempotency-Key giới hạn 191 byte và bản ghi phát lại được giữ 30 ngày theo mặc định.

Chúng trông giống nhau trong phản hồi nhưng mang ý nghĩa khác nhau:

TrườngVị tríÝ nghĩa
replayedcấp cao nhấtLệnh gọi này chưa từng tới nhà cung cấp — bạn đã phát lại một key.
cachedtrong từng kết quảKết luận của sản phẩm này được phục vụ từ cache kết quả.

Một lệnh gọi được phát lại tái tạo nguyên phản hồi gốc, kể cả giá trị cached của từng mục. Cả hai cờ đều không thay đổi số tiền bạn bị thu: thao tác phát lại không di chuyển tiền, và một lượt trúng cache vẫn bị tính theo đơn giá mỗi lần kiểm tra của sản phẩm.

Chỉ những kết quả đã quyết toán mới được lưu làm dữ kiện. Kết quả thất bại và unknown không được cache — lần kiểm tra sau cùng định danh với cùng sản phẩm sẽ hỏi lại nhà cung cấp thay vì phát lại một câu trả lời không kết luận.

Bạn thấy gìCần làm gì
Timeout, hoặc HTTP 500Gửi lại body gốc với key gốc. Kết quả chưa chắc chắn; đây chính là trường hợp mà key tồn tại vì nó.
409 request_in_progressChờ Retry-After, rồi gửi lại cùng body với cùng key.
409 idempotency_conflictKey đã mang một payload khác. Hãy tạo key mới — đừng sửa body rồi dùng lại key cũ.
429 realtime_rate_limitedChờ Retry-After. Không có gì được gửi đi, nên key cũ vẫn chưa dùng và an toàn để gửi.
503 realtime_route_unavailableKhông có gì được gửi đi. Thử lại sau, cùng key.

Điều tuyệt đối không được làm sau timeout là gửi một key mới với cùng công việc: nếu lệnh gọi đầu đã thành công, bạn vừa trả tiền cho lần kiểm tra đó hai lần.

HTTPcode
400idempotency_key_required — thiếu header
409request_in_progress — lệnh gọi gốc vẫn đang chạy
409idempotency_conflict — key được dùng lần đầu với payload khác