Preskočiť na obsah

Opakovanie a idempotencia

Siete zlyhávajú – najmä na mobile. Všetky Frontmail SDK neúspešné požiadavky automaticky opakujú, a to bezpečne: opakované odoslanie nikdy nevedie k duplicitnému e-mailu ani k dvojitému strhnutiu kreditov.

Situácia Opakuje sa?
Sieťová chyba (offline, DNS, prerušené spojenie) ✓
Timeout (timeoutMs, predvolene 15 s na pokus) ✓
Odpovede 5xx ✓
429 rate_limited ✓ – počká podľa Retry-After (ak je 60 s alebo menej)
Chyby 4xx – validácia, autentifikácia, origin, CAPTCHA ✗ – opakovanie by nepomohlo
Blokovanie na strane klienta (blockHeadless, blockList, limitRate) ✗

Predvolená politika: 3 opakovania po prvom pokuse, exponenciálny backoff začínajúci na 300 ms s plným jitterom, medzi pokusmi najviac 10 s. Nastavíte ju voľbou retry:

init({ publicKey: 'pk_4f2a…', retry: { retries: 5, baseDelayMs: 500, maxDelayMs: 20_000 } });
init({ publicKey: 'pk_4f2a…', retry: false }); // vypnutie

Každé logické volanie send() dostane ako Idempotency-Key náhodné UUID a všetky opakovania tohto odoslania používajú rovnaký kľúč. Frontmail si kľúče na serveri pamätá 24 hodín:

  • rovnaký kľúč s rovnakým telom vráti pôvodnú odpoveď (rovnaké message_id) a znova nič neodošle,
  • rovnaký kľúč s iným telom skončí chybou 409 idempotency_conflict.

Ak teda prvý pokus do Frontmailu v skutočnosti dorazil a stratila sa len odpoveď, opakovanie jednoducho dostane pôvodný výsledok.

Explicitný kľúč odovzdajte, keď sa môže opakovať samotný spúšťač – webhook doručený dvakrát, úloha, ktorá sa reštartuje, používateľ, ktorý odošle formulár dvakrát v dvoch kartách:

// @frontmail/node
await frontmail.send({ templateId: 'tpl_receipt', params, idempotencyKey: `receipt-${order.id}` });
// @frontmail/browser – voľby sú posledným argumentom
await send('svc_01J9…', 'tpl_receipt', params, { idempotencyKey: `receipt-${order.id}` });

Kľúč môže mať až 255 znakov. Pre každý samostatný e-mail použite nový kľúč – keď rovnaký kľúč použijete pre iný e-mail, namiesto odoslania dostanete chybu.

S REST API posielajte hlavičku sami:

Terminal window
curl https://api.frontmail.dev/v1/send \
-H 'Idempotency-Key: receipt-A-1042' \
-H 'Authorization: Bearer sk_…' \
-H 'Content-Type: application/json' \
-d '{ "template_id": "tpl_receipt", "template_params": { "order_id": "A-1042" } }'

Pri hromadnom odosielaní nastavte idempotencyKey (v REST API idempotency_key) pri každej správe zvlášť.

Len čo API vráti 202, o opakovanie doručenia sa stará Frontmail: odosielač opakuje prechodné chyby poskytovateľa s backoffom, pri chybách autentifikácie alebo trvalých chybách prepne na záložnú službu a keď je služba nefunkčná, správy pozdrží. Váš kód nemusí nič robiť – ak potrebujete, výsledok skontrolujte cez getStatus() alebo v Histórii.