+− THE DAILY DIFFdev & AI news
SHIP IT

Stripe își amintește cererea ta când răspunsul dispare

Un timeout poate lăsa o plată incertă după ce serverul a finalizat operațiunea.

Un timeout poate lăsa o plată incertă după ce serverul a finalizat operațiunea. Acest explicator "Under the Hood" folosește contractul de idempotență documentat al API-ului Stripe v1 pentru a arăta chei de operație stabile, reluarea răspunsului salvat, limitele de parametri și concurență, orizontul de retenție și reconcilierea rezultatului.

Citiți ediția scrisă (engleză) ↗

Ce acoperă acest videoclip

  • Idempotența se referă la efectul intenționat al repetării unei operațiuni. API-ul Stripe v1 adaugă un contract documentat de reluare a răspunsului salvat.
  • O reîncercare a aceleiași acțiuni logice folosește aceeași cheie și aceiași parametri. Păstrează cheia operațiunii peste apeluri SDK separate sau reporniri ale aplicației; o acțiune cu adevărat nouă necesită propria cheie.
  • După începerea execuției endpoint-ului, Stripe API v1 salvează starea și corpul primei cereri, inclusiv erorile 500, și returnează acest răspuns salvat la reîncercări.
  • Parametrii schimbați cu aceeași cheie produc o nepotrivire. Eșecurile de validare și conflictele de execuție concurente nu salvează niciun rezultat idempotent pentru acea încercare și pot fi reîncercate.
  • Stripe reține cheile API v1 pentru cel puțin 24 de ore și le poate șterge ulterior. Limitează reîncercările de rețea nerezolvate la primele 24 de ore, apoi oprește-te și reconciliază înainte de a repeta operațiunea.
  • O eroare 500 memorată în cache poate continua să se repete după ce conectivitatea este restabilită. Operațiunea originală poate avea efecte secundare; utilizează obiectul relevant, cererea din Dashboard și webhook-urile pentru a stabili rezultatul.
  • API v2 utilizează o semantică diferită de reluare. O cheie nu stabilește o livrare exact o dată universală pentru e-mail, inventar și fiecare operațiune locală a bazei de date.

Transcrierea tradusă

Tradus din narațiunea originală în engleză. Audio-ul și subtitrările disponibile sunt controlate de YouTube.

Un timeout ți-a anulat plata?

0:00 Crezi că un timeout înseamnă că plata ta a eșuat. Serverul poate finaliza operațiunea în timp ce răspunsul dispare, lăsând checkout-ul tău afișând cu încredere absolut nimic. De ce o reîncercare poate percepe din nou taxa? Cum își amintește Stripe o încercare? Când ar trebui să te oprești din reîncercări? Și ține minte un detaliu neplăcut. O eroare amintită poate supraviețui problemei de rețea.

0:17 Vom reveni la asta. Acesta este The Daily Diff, under the hood.

Ce identifică o cheie de idempotență?

0:21 Idempotența înseamnă că repetarea unei operațiuni are același efect intenționat ca și efectuarea ei o singură dată. O cheie de idempotență etichetează o acțiune logică. Versiunea unu a API-ului Stripe recunoaște acea etichetă la reîncercări și redă un răspuns salvat. Imaginează-ți că cumperi o cafea. Stripe completează cererea ta de plată, iar răspunsul se pierde la întoarcerea acasă. Clientul vede un "spinner". Banca lor ar putea avea o interpretare mai interesantă. O cerere de creare neprotejată poate repeta efectul secundar.

Cum face aceeași cheie o reîncercare sigură?

0:45 Atașează o cheie unică înainte de prima încercare și păstreaz-o pentru reîncercări. Dacă aplicația ta repornește, păstrează acea cheie cu operațiunea în înregistrările tale. Pentru API-ul Stripe versiunea unu, odată ce execuția endpoint-ului începe, starea și corpul primei cereri sunt salvate. Trimite din nou aceeași cheie și aceiași parametri, iar Stripe returnează răspunsul salvat. Cafeaua rămâne pe loc în timp ce bonul ei călătorește din nou.

Ce anume salvează Stripe?

1:07 Iată formularea reală a lui Stripe. Reîncercările cu aceeași cheie returnează răspunsul salvat, inclusiv erorile cinci sute. Documentația face mai multă treabă decât helper-ul tău de reîncercare numit optimist. Clientul apasă din nou. Aplicația ta decide dacă asta reia achiziția în așteptare sau începe una nouă. O cafea cu adevărat nouă primește o cheie nouă. O cheie proaspătă pentru fiecare reîncercare de rețea anulează protecția.

1:27 Parametrii diferiți cu aceeași cheie declanșează o nepotrivire.

Ce se întâmplă când cererea se schimbă?

1:30 Dacă parametrii nu trec validarea, sau o altă cerere cu acea cheie este încă în execuție, Stripe nu salvează niciun rezultat idempotent pentru acea încercare. Acele cereri pot fi reîncercate. O cerere "racing" primește un conflict. Acestea sunt regulile versiunii unu. Versiunea doi se comportă diferit. Un antet nu poate promite livrare exact o dată în întregul tău sistem. Emailul, inventarul și baza de date au nevoie fiecare de gestionarea erorilor.

1:52 Cheia protejează operațiunea în cadrul domeniului său documentat. Stripe reține cheile versiunii unu pentru cel puțin douăzeci și patru de ore și le poate șterge

Cât timp este sigur să reîncerci rezultatul memorat?

1:59 ulterior. O cheie ștearsă poate executa o nouă cerere. Păstrează reîncercările nerezolvate în prima zi. Dincolo de asta, oprește-te și reconciliază rezultatul original. Utilizează "exponential backoff" și "jitter" pentru a oferi serverului un răgaz. Altfel, reîncercările formează o coadă în fața unei cafenele în flăcări. Bibliotecile Stripe gestionează reîncercările, dar verifică setările implicite ale bibliotecii tale. Acea eroare persistentă este capcana.

De ce poate o eroare memorată să reapară?

2:20 Un răspuns "cinci sute" memorat în cache continuă să se repete după ce conectivitatea este restabilită. Operațiunea originală ar fi putut produce efecte secundare. Rezolvă rezultatul folosind obiecte, Dashboard-ul și webhook-urile. O cheie nouă poate repeta acțiunea. Dacă preferi să citești asta decât să mă auzi spunând-o, "diff"-ul ajunge în căsuța ta poștală în fiecare dimineață, gratuit la the daily diff dot dev, link mai jos.

Aș implementa un buton de reîncercare cu acest contract?

2:39 Verdict, under the hood. SHIP IT. Aș implementa chei stabile cu reîncercări limitate și reconciliere, astfel încât clienții să primească cafea fără a-ți finanța educația în sisteme distribuite. Și asta e diferența pentru astăzi. Sunt Niko de la Axrisi. Îmbină responsabil.

Surse

  1. Idempotent requestsStripe Docs
  2. Designing robust and predictable APIs with idempotencyStripe Engineering — Brandur Leach
  3. Advanced error handlingStripe Docs
  4. HTTP Semantics — RFC 9110 §9.2.2 Idempotent MethodsIETF / RFC Editor

Videoclipuri similare