Idempotencia: bezpečné opakovanie požiadaviek
Sieť sa dokáže pokaziť medzi „server prácu urobil“ a „vy ste dostali odpoveď“. Kľúč idempotencie vám dovolí zopakovať POST bez toho, aby sa práca urobila dvakrát, takže vypršanie času nikdy nevytvorí duplicitný lead ani faktúru. Anglická verzia: Idempotency.
Ako funguje hlavička Idempotency-Key
Section titled “Ako funguje hlavička Idempotency-Key”K POST požiadavke pridajte hlavičku Idempotency-Key s najviac 255 znakmi. Prvá požiadavka s daným kľúčom prebehne normálne a jej odpoveď sa uloží na 24 hodín pre daný API kľúč. Opakovanie s rovnakým kľúčom a rovnakou požiadavkou vráti uložený stav a telo bez ďalšieho spracovania a odpoveď má hlavičku Idempotent-Replayed: true. Bez hlavičky sa požiadavky nikdy nededuplikujú. Týka sa to len POST.
Čo je rovnaká požiadavka
Section titled “Čo je rovnaká požiadavka”Dakoty si vezme odtlačok z metódy, cesty, dopytu a tela. Ten istý kľúč s iným telom alebo na inom koncovom bode vráti 422 IDEMPOTENCY_KEY_REUSED. Pri opakovaní pošlite totožné telo, vrátane poradia polí a hodnôt. Kľúče sú viazané na jeden API kľúč, takže dva kľúče môžu použiť rovnaký reťazec bez kolízie.
Ktoré odpovede sa ukladajú
Section titled “Ktoré odpovede sa ukladajú”Ukladajú a opakujú sa úspešné odpovede (2xx) a deterministické chyby validácie (400 a 422). Všetko ostatné kľúč uvoľní: chyby 5xx, 401, 403, 404, 409 a 429 sa neukladajú, takže po oprave príčiny môžete zopakovať požiadavku s tým istým kľúčom. Odpovede väčšie ako 1 MiB sa tiež neukladajú. Ak je úložisko kľúčov nedostupné, požiadavka sa vykoná bez deduplikácie, preto si pri kritických zápisoch držte vlastnú ochranu pred duplicitami.
Požiadavky, ktoré ešte bežia
Section titled “Požiadavky, ktoré ešte bežia”Ak zopakujete požiadavku, kým prvá ešte beží, dostanete 409 IDEMPOTENCY_IN_PROGRESS. Chvíľu počkajte a pošlite tú istú požiadavku znova, po dokončení prvej dostanete jej uloženú odpoveď.
Ako zvoliť dobrý kľúč
Section titled “Ako zvoliť dobrý kľúč”Použite hodnotu, ktorá je stabilná pre jednu logickú operáciu a jedinečná medzi operáciami. Funguje UUID vytvorené raz pre jednu obchodnú akciu aj identifikátor z vášho systému, napríklad objednavka-4711-faktura. Nevytvárajte nový kľúč vnútri slučky opakovania, lebo potom by každý pokus vyzeral ako nová operácia.
Bezpečné opakovanie v Node.js
Section titled “Bezpečné opakovanie v Node.js”Kľúč vznikne raz pred prvým pokusom a používa sa pri každom opakovaní. Ukážka stavia na pomocnej funkcii zo stránky Chyby a limity a potrebuje Node.js 18 alebo novší.
import { randomUUID } from "node:crypto";
export async function createLead(lead, key = randomUUID()) { for (let attempt = 0; attempt < 4; attempt++) { try { const res = await fetch("https://api.dakoty.com/api/v1/public/leads", { method: "POST", headers: { Authorization: `Bearer ${process.env.DAKOTY_API_KEY}`, "Content-Type": "application/json", "Idempotency-Key": key, }, body: JSON.stringify(lead), }); if (res.status === 409 || res.status >= 500) throw new Error(`retry ${res.status}`); return { replayed: res.headers.get("idempotent-replayed") === "true", body: await res.json() }; } catch (err) { if (attempt === 3) throw err; await new Promise((resolve) => setTimeout(resolve, 2 ** attempt * 500)); } }}Bezpečné opakovanie v Pythone
Section titled “Bezpečné opakovanie v Pythone”Rovnaký princíp s balíkom requests. Kľúč vzniká pred slučkou a rovnaký slovník dáva pri každom pokuse rovnaké telo JSON.
import osimport timeimport uuidimport requests
def create_lead(lead, key=None): key = key or str(uuid.uuid4()) headers = { "Authorization": f"Bearer {os.environ['DAKOTY_API_KEY']}", "Idempotency-Key": key, } for attempt in range(4): try: r = requests.post("https://api.dakoty.com/api/v1/public/leads", json=lead, headers=headers, timeout=30) if r.status_code != 409 and r.status_code < 500: return r.headers.get("Idempotent-Replayed") == "true", r.json() except requests.RequestException: if attempt == 3: raise time.sleep(2**attempt * 0.5) raise RuntimeError("Dakoty did not accept the request after 4 attempts")