เอเจนต์ของคุณเรียกใช้ปลายทางสำหรับการชำระเงิน การร้องขอสำเร็จ การเรียกเก็บเงินเกิดขึ้น แต่การตอบกลับหมดเวลาขณะเดินทางกลับ เอเจนต์ไม่เคยเห็นรหัส 200 ดังนั้นจึงทำตามที่คุณสั่งเมื่อเกิดข้อผิดพลาด: มันลองใหม่ ตอนนี้ลูกค้าถูกเรียกเก็บเงินสองครั้งแล้ว และไม่มีอะไรในบันทึกของคุณที่ดูเหมือนข้อผิดพลาดเลย
นี่คือโหมดความล้มเหลวที่แยกเอเจนต์ออกจากไคลเอนต์ API ทั่วไป มนุษย์ที่คลิก “ชำระเงิน” เพียงครั้งเดียวจะเห็นสปินเนอร์และรอ เอเจนต์ที่อยู่ในวงจรการลองใหม่จะเห็นความเงียบและพยายามอีกครั้ง บางครั้งถึงสามหรือสี่ครั้งติดต่อกัน เร็วกว่าที่มนุษย์จะทำได้ นโยบายการลองใหม่ทุกครั้งที่คุณเพิ่มเพื่อให้เอเจนต์น่าเชื่อถือขึ้น ยังทำให้การเขียนซ้ำมีโอกาสเกิดขึ้นได้มากขึ้น วิธีแก้คือ Idempotency: การทำให้การร้องขอซ้ำ ๆ เกิดผลลัพธ์เช่นเดียวกับการร้องขอครั้งเดียว
คู่มือนี้ครอบคลุมความหมายของ idempotency ในระดับ HTTP, วิธีการสร้างคีย์ที่เอเจนต์สามารถนำกลับมาใช้ใหม่ได้จริง, สิ่งที่เซิร์ฟเวอร์ต้องจัดเก็บเพื่อรองรับคีย์เหล่านั้น, และวิธีทดสอบทั้งหมดก่อนที่ลูกค้าจริงจะถูกเรียกเก็บเงินสองครั้ง หากคุณยังไม่ได้อ่านบทความหลักของเราเกี่ยวกับ สาเหตุที่เอเจนต์ AI ล้มเหลวในการทำงานจริง, การเขียนซ้ำคือโหมดความล้มเหลวที่ซ่อนอยู่เบื้องหลังรายงานส่วนใหญ่ที่ระบุว่า "เอเจนต์ทำซ้ำสองครั้ง"
Apidog ปรากฏอยู่ในส่วนของการทดสอบของเรื่องนี้ Idempotency เป็นสิ่งที่คุณสร้างลงใน API และเลเยอร์เครื่องมือของเอเจนต์ของคุณ สิ่งที่คุณต้องการหลังจากนั้นคือวิธีส่งคำขอเดียวกันสองครั้งและพิสูจน์ว่าครั้งที่สองไม่ได้เปลี่ยนแปลงอะไรเลย ซึ่งเป็นการทดสอบที่คุณสามารถบันทึกและรันใน CI ได้
ทำไมเอเจนต์ถึงทำลาย Idempotency บ่อยกว่ามนุษย์
สามประการเกี่ยวกับปริมาณการใช้งานของเอเจนต์ที่ทำให้เกิดการซ้ำกันบ่อยครั้ง
ประการแรกคือปริมาณการลองใหม่ เฟรมเวิร์กของเอเจนต์จะลองใหม่อย่างรุนแรงเป็นค่าเริ่มต้น เนื่องจากความล้มเหลวของเครือข่ายชั่วคราวเป็นสาเหตุที่พบบ่อยที่สุดของการทำงานที่ผิดพลาด คู่มือของเราเกี่ยวกับ การกู้คืนข้อผิดพลาดของเอเจนต์ อธิบายถึง backoff และ circuit breakers และทุกเทคนิคในนั้นจะเพิ่มจำนวนครั้งที่คำขอหนึ่งๆ เข้าสู่เซิร์ฟเวอร์ของคุณ
ประการที่สองคือความคลุมเครือของการหมดเวลา เมื่อคำขอหมดเวลา ไคลเอนต์จะไม่ได้รับข้อมูลใดๆ ว่าเซิร์ฟเวอร์ประมวลผลคำขอหรือไม่ รหัส 504 จากพร็อกซีอาจหมายความว่าการเขียนไม่เคยเกิดขึ้น หรือเกิดขึ้นแล้วแต่การตอบกลับหายไป มนุษย์มักจะตรวจสอบก่อนที่จะลองใหม่ แต่อีเจนต์มักจะไม่ทำเช่นนั้น เพราะ “ตรวจสอบก่อน” เป็นการเรียกใช้เครื่องมือเพิ่มเติมที่โมเดลต้องตัดสินใจทำ
ประการที่สามคือวงจรการทำงาน เอเจนต์ที่ทำงานล้มเหลวอาจเริ่มงานทั้งหมดใหม่ ไม่ใช่แค่ขั้นตอนที่ล้มเหลวเท่านั้น หากขั้นตอนแรกสร้างคำสั่งซื้อและขั้นตอนที่สี่ล้มเหลว การรีสตาร์ทแบบธรรมดาจะสร้างคำสั่งซื้อที่สอง นี่คือจุดที่เอเจนต์แบบหลายขั้นตอนแตกต่างจากสคริปต์อย่างชัดเจน: ขอบเขตการลองใหม่ไม่ชัดเจน และโมเดลไม่ใช่โค้ดของคุณ ที่ตัดสินใจว่าจะเริ่มตรงไหน
เมื่อนำทั้งหมดมารวมกัน คุณก็จะเห็นภาพของปัญหา ไม่ใช่ว่าเอเจนต์ส่งคำขอที่ไม่ถูกต้อง พวกเขาส่งคำขอที่ถูกต้องหลายครั้ง
Idempotency รับประกันอะไรบ้าง
การดำเนินการเป็น idempotent เมื่อดำเนินการหลายครั้งแล้วมีผลลัพธ์เช่นเดียวกับการดำเนินการเพียงครั้งเดียว เมธอด GET, PUT และ DELETE ถูกกำหนดให้เป็น idempotent ใน RFC 9110 ซึ่งเป็นข้อกำหนดด้านความหมายของ HTTP ส่วน POST ไม่ใช่ ซึ่งเป็นสาเหตุที่การดำเนินการที่อันตรายมักจะเป็นการเรียกใช้ POST เช่น การสร้างคำสั่งซื้อ การส่งข้อความ การเริ่มการโอนเงิน
คำชี้แจงสองข้อช่วยลดความสับสนได้มาก
Idempotent ไม่เหมือนกับ safe เมธอดที่ safe จะไม่เปลี่ยนแปลงอะไรเลย DELETE เป็น idempotent แต่เป็นการทำลาย: การเรียกใช้ห้าครั้งจะทำให้ทรัพยากรถูกลบไปแล้ว เช่นเดียวกับการเรียกใช้ครั้งเดียว แต่ทรัพยากรก็ยังคงหายไป เอเจนต์ต้องการคุณสมบัติทั้งสองนี้แยกกัน ซึ่งเป็นข้อโต้แย้งในโพสต์ของเราเกี่ยวกับ คีย์ API ที่มีสิทธิ์น้อยที่สุดสำหรับเอเจนต์ จากฝั่งของข้อมูลรับรอง
Idempotent ไม่เหมือนกับการตอบกลับที่เหมือนกัน การเรียกใช้ครั้งที่สองอาจส่งคืนผลลัพธ์ที่จัดเก็บไว้ของการเรียกใช้ครั้งแรก และอาจส่งคืนรหัสสถานะที่แตกต่างกัน สิ่งที่ไม่ควรเปลี่ยนแปลงคือสถานะบนเซิร์ฟเวอร์ การเรียกเก็บเงินครั้งเดียว คำสั่งซื้อเดียว อีเมลฉบับเดียว
Idempotency keys: รูปแบบที่ทำให้ POST ปลอดภัย
วิธีแก้ปัญหามาตรฐานคือคีย์ที่สร้างโดยไคลเอนต์ที่ส่งมาพร้อมกับคำขอ เซิร์ฟเวอร์จะบันทึกคีย์พร้อมกับผลลัพธ์ และคำขอใดๆ ในภายหลังที่ส่งคีย์เดียวกันจะส่งคืนผลลัพธ์ที่บันทึกไว้แทนที่จะทำงานซ้ำอีกครั้ง
Stripe ได้ทำให้เฮดเดอร์นี้เป็นที่นิยม และ เอกสาร Idempotency ของ Stripe ยังคงเป็นคำอธิบายที่ชัดเจนที่สุดเกี่ยวกับความหมาย นอกจากนี้ยังมีความพยายามของ IETF ที่จะกำหนดให้เป็นมาตรฐานในชื่อ ฟิลด์เฮดเดอร์ Idempotency-Key ซึ่งเป็นสิ่งที่ควรค่าแก่การอ่านก่อนที่คุณจะตั้งชื่อเฮดเดอร์ของคุณเอง
คำขอมีลักษณะดังนี้:
POST /v1/payments HTTP/1.1
Host: api.yourservice.com
Authorization: Bearer sk_live_...
Idempotency-Key: 9f2b7c14-6d3a-4b18-9d55-1e2a7c0b4f31
Content-Type: application/json
{
"amount": 4900,
"currency": "usd",
"customer_id": "cus_8812",
"description": "Pro plan, August"
}
คีย์เป็น UUID มันไม่มีความหมายสำหรับเซิร์ฟเวอร์นอกเหนือจาก “นี่คือการดำเนินการเชิงตรรกะเดียวกัน” เซิร์ฟเวอร์จัดเก็บคีย์นี้พร้อมกับลายนิ้วมือของเนื้อหาคำขอและการตอบกลับที่สร้างขึ้น
การสร้างคีย์ที่เอเจนต์สามารถนำกลับมาใช้ใหม่ได้
นี่คือจุดที่การใช้งานเอเจนต์ส่วนใหญ่ผิดพลาด หาก wrapper ของเครื่องมือสร้าง UUID ใหม่ทุกครั้งที่เรียกใช้ คีย์จะเปลี่ยนไปทุกครั้งที่ลองใหม่ และ idempotency จะไม่มีผล คีย์จะต้องเชื่อมโยงกับการดำเนินการเชิงตรรกะ ไม่ใช่กับการพยายามเรียกใช้ HTTP
กฎคือ: สร้างคีย์เมื่อเอเจนต์ตัดสินใจที่จะดำเนินการ และเก็บคีย์นั้นไว้สำหรับการลองใหม่ทุกครั้งของการตัดสินใจนั้น
import uuid
class PaymentTool:
def __init__(self, client):
self.client = client
self._keys = {}
def charge(self, task_id, step_id, amount, customer_id):
# One key per (task, step). Retries of the same step reuse it.
op = f"{task_id}:{step_id}"
if op not in self._keys:
self._keys[op] = str(uuid.uuid4())
return self.client.post(
"/v1/payments",
headers={"Idempotency-Key": self._keys[op]},
json={"amount": amount, "customer_id": customer_id},
)
คีย์แบบกำหนดได้ก็ใช้ได้เช่นกัน และมันจะคงอยู่รอดจากการรีสตาร์ทกระบวนการ ซึ่งพจนานุกรมในหน่วยความจำไม่สามารถทำได้:
import hashlib
def idempotency_key(task_id: str, step_id: str, payload: dict) -> str:
raw = f"{task_id}|{step_id}|{sorted(payload.items())}"
return hashlib.sha256(raw.encode()).hexdigest()[:32]
สร้างคีย์จาก task run และ step เสมอ ห้ามสร้างจาก timestamp หรือค่าสุ่มที่สร้างใหม่ทุกครั้งที่พยายาม หากเอเจนต์รีสตาร์ทงานทั้งหมดและตั้งใจจะเรียกเก็บเงินใหม่ task ID จะเปลี่ยนไป และคีย์ก็จะเปลี่ยนตามไปด้วย นั่นคือพฤติกรรมที่คุณต้องการ
สิ่งที่เซิร์ฟเวอร์ต้องทำ
การจัดการเฮดเดอร์อย่างถูกต้องนั้นซับซ้อนกว่าแค่การค้นหา การใช้งานที่ถูกต้องจะทำสี่สิ่งนี้:
- เมื่อได้รับ ให้พยายามจองคีย์ แทรกคีย์ลงในตารางที่มีข้อจำกัด UNIQUE ก่อนที่จะทำงานใดๆ หากการแทรกล้มเหลว หมายความว่ามีการพยายามอื่นเป็นเจ้าของคีย์นั้นแล้ว
- หากคีย์มีอยู่และลายนิ้วมือของคำขอที่จัดเก็บไว้แตกต่างกัน ให้ปฏิเสธด้วย
422คีย์เดียวกันแต่มีเนื้อหาแตกต่างกันหมายถึงข้อผิดพลาดของไคลเอนต์ และการส่งคืนผลลัพธ์เก่าโดยไม่มีการแจ้งเตือนจะเป็นการซ่อนข้อผิดพลาดนั้น - หากคีย์มีอยู่และการพยายามครั้งแรกยังคงอยู่ระหว่างดำเนินการ ให้ส่งคืน
409เพื่อให้ผู้เรียกถอยกลับแทนที่จะพยายามแข่งขัน - เมื่อทำงานเสร็จสิ้น ให้จัดเก็บรหัสสถานะและเนื้อหาที่เชื่อมโยงกับคีย์ จากนั้นส่งคืนสำหรับทุกการเรียกใช้ในภายหลัง
CREATE TABLE idempotency_records (
key TEXT PRIMARY KEY,
request_hash TEXT NOT NULL,
state TEXT NOT NULL, -- in_progress | completed
response_status INT,
response_body JSONB,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
expires_at TIMESTAMPTZ NOT NULL
);
กำหนดวันหมดอายุ ยี่สิบสี่ชั่วโมงครอบคลุมช่วงเวลาการลองใหม่ที่สมจริง และการเก็บคีย์ไว้ตลอดไปจะทำให้ตารางกลายเป็นภาระ Stripe หมดอายุคีย์หลังจาก 24 ชั่วโมง ซึ่งเป็นค่าเริ่มต้นที่เหมาะสมที่จะคัดลอก
การทดสอบว่าการเรียกครั้งที่สองไม่ได้เปลี่ยนแปลงอะไรเลย
การสร้าง idempotency คือครึ่งหนึ่งของงาน การพิสูจน์ว่ามันทำงานได้จริงคืออีกครึ่งหนึ่ง และเป็นส่วนที่มักจะถูกข้ามไป เพราะเส้นทางที่สำเร็จจะดูเหมือนกันไม่ว่าฟีเจอร์จะทำงานหรือไม่ก็ตาม
การทดสอบนั้นอธิบายได้ง่ายๆ: ส่งคำขอ, เก็บผลลัพธ์, ส่งคำขอเดียวกันซ้ำอีกครั้ง, และยืนยันว่าเซิร์ฟเวอร์ไม่ได้ทำงานซ้ำสองครั้ง ส่วนที่ยากคือการยืนยันครั้งสุดท้าย เพราะการตอบกลับเพียงอย่างเดียวจะไม่บอกคุณ การเรียกเก็บเงินที่สำเร็จสองครั้งต่างก็ส่งคืน 200
ดังนั้น ให้ยืนยันที่สถานะ ไม่ใช่ที่การตอบกลับ:
- เนื้อหาการตอบกลับครั้งที่สองตรงกับครั้งแรก รวมถึง ID ของทรัพยากร ID ใหม่หมายถึงมีการสร้างทรัพยากรใหม่
- การเรียกใช้
GETติดตามบนคอลเล็กชันจะส่งคืนหนึ่งรายการ ไม่ใช่สองรายการ - ตัวนับหรือยอดคงเหลือใดๆ เปลี่ยนแปลงไปเพียงครั้งเดียว
ใน Apidog คุณสามารถตั้งค่าสิ่งนี้เป็นสถานการณ์ทดสอบได้: ขั้นตอนที่หนึ่งส่ง POST ด้วย Idempotency-Key ที่กำหนดไว้ ขั้นตอนที่สองทำซ้ำ และขั้นตอนที่สามแสดงรายการทรัพยากรและยืนยันจำนวน บันทึก ID การตอบกลับจากขั้นตอนที่หนึ่งลงในตัวแปร และยืนยันว่าขั้นตอนที่สองส่งคืนค่าเดียวกัน เนื่องจากสถานการณ์ทั้งหมดถูกจัดเก็บไว้ มันจะทำงานใน CI ทุกครั้งที่มีการเปลี่ยนแปลงเส้นทางการชำระเงิน ซึ่งเป็นที่ที่ข้อผิดพลาดมักจะปรากฏ เทคนิคเดียวกันนี้สามารถนำไปใช้กับรูปแบบที่กว้างขึ้นใน คู่มือการทดสอบสัญญา API ของเราได้

อีกสองกรณีที่ควรกล่าวถึง เพราะมันสามารถตรวจจับข้อผิดพลาดจริงได้:
- คีย์เดียวกัน แต่เนื้อหาแตกต่างกัน คาดว่าจะได้รับ
422ไม่ใช่ความสำเร็จแบบเงียบๆ - คำขอซ้ำที่เกิดขึ้นพร้อมกัน ส่งคำขอทั้งสองพร้อมกันและยืนยันว่ามีเพียงหนึ่งเดียวที่สำเร็จ สิ่งนี้ช่วยตรวจจับข้อจำกัด UNIQUE ที่ขาดหายไป ซึ่งการทดสอบตามลำดับจะไม่สามารถเปิดเผยได้
การจำลองก็ช่วยได้เช่นกัน หากคุณยังคงสร้างเอเจนต์และ API การชำระเงินยังไม่มีอยู่ ให้จำลองมันด้วยการตอบกลับที่คำนึงถึง idempotency เพื่อให้ตรรกะการลองใหม่ของเอเจนต์ได้รับการทดสอบตั้งแต่เนิ่นๆ โพสต์ของเราเกี่ยวกับ ทำไมเอเจนต์ควรกระทบกับ mocks แทนที่จะเป็น production ชี้ให้เห็นถึงความสำคัญของพฤติกรรมนี้ในวงกว้างขึ้น
ในกรณีที่ไม่สามารถเพิ่มคีย์ได้
บางครั้ง API ไม่ใช่ของคุณและไม่มีการรองรับ idempotency คุณยังมีทางเลือกอยู่ โดยเรียงตามลำดับความพึงพอใจโดยประมาณ
ทำให้การดำเนินการเป็น idempotent โดยธรรมชาติ การใช้เมธอด PUT ไปยังพาธของทรัพยากรที่ไคลเอนต์เลือกนั้นเป็น idempotent โดยโครงสร้าง: PUT /orders/{client_order_id} หากคุณควบคุมการออกแบบ API ควรเลือกวิธีนี้มากกว่าการใช้ POST พร้อมเฮดเดอร์ ซึ่งไม่จำเป็นต้องมีตารางเพิ่มเติม
ตรวจสอบก่อนเขียน ให้เอเจนต์สอบถามหารายการที่มีอยู่ด้วยคีย์ธรรมชาติเดียวกันก่อนที่จะสร้างรายการใหม่ วิธีนี้อ่อนแอกว่าเล็กน้อย เพราะการแข่งกันระหว่างการตรวจสอบและการเขียนยังคงสามารถสร้างสองรายการได้ แต่ก็ช่วยแก้ปัญหากรณีการหมดเวลาที่พบบ่อยได้
กำจัดข้อมูลซ้ำที่ปลายทาง หากการเขียนเป็นข้อความหรือเหตุการณ์ ให้ทำการกำจัดข้อมูลซ้ำที่ตัวรับสาร แนบ ID ข้อความที่เสถียรและให้ตัวรับสารทิ้งรายการที่ซ้ำกัน นี่เป็นแนวปฏิบัติมาตรฐานในระบบที่ขับเคลื่อนด้วยเหตุการณ์และสอดคล้องกับคำแนะนำใน คู่มือ webhook ที่น่าเชื่อถือ ของเรา
จำกัดการดำเนินการ สำหรับการดำเนินการที่ไม่สามารถย้อนกลับได้อย่างแท้จริงและไม่สามารถทำให้เป็น idempotent ได้ ให้มีมนุษย์เข้ามาเกี่ยวข้อง นั่นคือรูปแบบ approval-gate จากโพสต์ของเราเกี่ยวกับ AI agent guardrails และเป็นคำตอบที่ถูกต้องเมื่อต้นทุนของการซ้ำซ้อนสูงเพียงพอ
รู้ว่าการรันใดทำอะไร
Idempotency หยุดการซ้ำกันได้ แต่ไม่ได้บอกคุณว่าการพยายามครั้งใดที่สร้างรายการ และนั่นคือคำถามที่คุณจะถูกถามหลังเกิดเหตุการณ์
รักษาข้อมูลประจำตัวของการรันให้แนบไปกับงาน เมื่อเอเจนต์เป็นบริการของคุณเอง นั่นหมายถึง ID งานและ ID ขั้นตอนจากการสร้างคีย์ข้างต้น ซึ่งถูกบันทึกไว้กับการพยายามทุกครั้ง เมื่อเอเจนต์เป็นรันไทม์โค้ดที่ดำเนินการที่ได้รับมอบหมาย แพลตฟอร์มมักจะเก็บข้อมูลนี้ไว้ให้คุณ: ใน Sharkly แต่ละการรันจะถูกเชื่อมโยงกับ Task ที่มาด้วย โดยมีสถานะการดำเนินการและผลลัพธ์จัดเก็บไว้พร้อมกับกระทู้ความคิดเห็น ดังนั้นการเขียนซ้ำจึงสามารถย้อนกลับไปยังการรันที่เฉพาะเจาะจงได้ แทนที่จะเป็นการลองใหม่ที่ไม่ระบุตัวตน

รายการตรวจสอบก่อนการนำไปใช้งาน
- เครื่องมือที่ไม่เป็น idempotent ทุกชิ้นที่เอเจนต์สามารถเรียกใช้ได้จะต้องมี idempotency key และตัว wrapper ของเครื่องมือจะปฏิเสธที่จะส่งหากไม่มี
- คีย์จะมาจาก task และ step ไม่ใช่จากการพยายาม
- เซิร์ฟเวอร์จะจองคีย์ก่อนที่จะทำงาน ไม่ใช่หลังจากนั้น
- คีย์เดียวกันแต่มี payload แตกต่างกันจะส่งคืนข้อผิดพลาด แทนที่จะเป็นการตอบกลับที่แคชไว้
- คำขอซ้ำที่เกิดขึ้นพร้อมกันจะถูกจัดการโดยข้อจำกัดของฐานข้อมูล ไม่ใช่โดยการจับเวลาของแอปพลิเคชัน
- การทดสอบที่บันทึกไว้จะพิสูจน์ว่าการเรียกครั้งที่สองไม่ได้เปลี่ยนแปลงอะไรเลย และมันจะทำงานใน CI
- คีย์จะหมดอายุตามกำหนดเวลาและตารางจะถูกล้าง
ทำตามรายการนั้น และเรื่องราวการเรียกเก็บเงินซ้ำซ้อนก็จะไม่เกิดขึ้นอีกต่อไป ซึ่งหมายความว่านโยบายการลองใหม่ของคุณสามารถก้าวร้าวขึ้นได้แทนที่จะน้อยลง นั่นคือผลตอบแทนที่แท้จริง: idempotency คือสิ่งที่ช่วยให้คุณสร้างเอเจนต์ที่ทนทานได้โดยไม่ทำให้เกิดอันตราย
คำถามที่พบบ่อย
จำเป็นต้องมี idempotency keys สำหรับเครื่องมือแบบอ่านอย่างเดียวหรือไม่? ไม่จำเป็น คำขอ GET เป็น idempotent และปลอดภัยอยู่แล้ว ดังนั้นการลองใหม่จะมีค่าใช้จ่ายเพียงเล็กน้อยในด้าน latency เท่านั้น และไม่มีอะไรอื่น สำรองคีย์ไว้สำหรับการเรียกใช้ที่สร้าง, เรียกเก็บเงิน, ส่ง, หรือเปลี่ยนแปลงสถานะอื่นๆ
ควรสร้างคีย์ที่ไหน ในเอเจนต์หรือใน wrapper ของเครื่องมือ? ใน wrapper ของเครื่องมือ โดยใช้ ID ของ task และ step ของเอเจนต์เป็นหลัก การปล่อยให้โมเดลสร้างคีย์เป็นความผิดพลาด: โมเดลจะสร้างค่าใหม่เมื่อมีการลองใหม่และอาจทำให้เกิดการชนกันข้ามงานได้
คำขอซ้ำควรส่งคืนรหัสสถานะใด? ให้ส่งคืนสถานะที่จัดเก็บไว้จากการเรียกใช้ครั้งแรก ดังนั้น POST ครั้งที่สองที่ครั้งแรกส่งคืน 201 ก็จะส่งคืน 201 อีกครั้งพร้อมเนื้อหาเดิม API บางแห่งเพิ่มเฮดเดอร์ เช่น Idempotent-Replay: true เพื่อระบุว่าเป็นคำขอซ้ำ ซึ่งมีประโยชน์สำหรับการดีบักและไม่เป็นอันตรายต่อไคลเอนต์ที่ละเว้นมัน
ควรเก็บคีย์ไว้นานแค่ไหน? ยี่สิบสี่ชั่วโมงครอบคลุมช่วงเวลาการลองใหม่เกือบทั้งหมด การเก็บไว้นานกว่านั้นไม่ค่อยมีประโยชน์และทำให้ตารางขยายใหญ่ขึ้นโดยไม่มีขอบเขต หากไคลเอนต์ลองใหม่หลังจากช่วงเวลาดังกล่าว ให้ถือว่าเป็นการดำเนินการใหม่
สิ่งนี้ใช้แทน transaction ได้หรือไม่? ไม่ได้ Idempotency keys หยุดคำขอซ้ำไม่ให้สร้างผลลัพธ์ซ้ำ Transaction ทำให้คำขอเดียวเป็น atomic คุณต้องมีทั้งสองอย่าง และการจองคีย์ควรถูเขียนใน transaction เดียวกันกับการทำงานเมื่อใดก็ตามที่ฐานข้อมูลของคุณอนุญาต
จะทดสอบสิ่งนี้ได้อย่างไรโดยไม่มีผู้ให้บริการชำระเงินจริง? ชี้เอเจนต์ไปยัง mock ที่มีการใช้งานตามความหมายของคีย์ รวมถึง 422 เมื่อ payload ไม่ตรงกัน คู่มือของเราเกี่ยวกับ การทดสอบเอเจนต์ AI กับ API แบบจำลอง ครอบคลุมการตั้งค่า และ ดาวน์โหลด Apidog หากคุณต้องการ mock และการทดสอบการลองใหม่ที่อยู่ในโปรเจกต์เดียวกัน
