Digitális és informatikai

API-időtúllépés után: újraküldés előtt olvasd vissza az eredményt

A hálózati hiba nem bizonyítja, hogy a szerver nem mentett. Egy új cikk létrehozásának és egy meglévő revízió védelmének példáján járjuk végig a biztonságos folytatást.

Dajka Gábor6 perc olvasás

Egy importáló elküld egy új cikket, majd időtúllépést kap. A kezelő újraindítja a teljes folyamatot, és később két bejegyzés jelenik meg. A probléma abból adódhat, hogy az első kérés mentése már megtörtént, csak a válasz nem jutott vissza a klienshez.

Az időtúllépés ezért bizonytalan kimenetet jelent. A következő lépést a szerveroldali állapot visszaolvasása és az API dokumentált ismétlési szerződése alapján kell kiválasztani. A puszta „próbáld újra” kezelés írási műveleteknél nem mindig biztonságos.

Változatlan azonosítóval tedd ellenőrizhetővé a mentést

Saját mintafolyamatunkban az új cikk azonosítója minta-szamitas-ellenorzese, a létrehozáskor elvárt korábbi revízió pedig 0. Ez azt jelenti, hogy az adott azonosító alatt még nem létezhet korábbi bejegyzés. A szerver ellenőrzi ezt a feltételt, és sikeres mentéskor létrehozza az első revíziót.

Ha a kliens nem kap választ, először ugyanezt az azonosítót olvassa vissza. Ha az első revízió létezik, és tartalma megegyezik a feltöltött adatokkal, a létrehozás sikeresnek tekinthető. Nincs szükség egy második, számozott vagy véletlen azonosítójú cikkre.

Ha a visszaolvasás sem sikerül, az eredmény továbbra is ismeretlen. Ilyenkor a folyamat álljon meg egyértelmű állapotjelzéssel. A bizonytalanságot ne nevezze automatikusan sikertelen mentésnek.

Meglévő cikknél a revíziót is egyeztesd

Egy másik példában egy cikket az 5. revízióból szeretnél módosítani. Közben egy szerkesztő már elmentette a 6. revíziót. Ha a kliens csak az azonosítót használja, felülírhatja a szerkesztő újabb munkáját.

A feltételes mentés az elvárt 5. revíziót is elküldi. A szerver a tényleges 6. revízió miatt konfliktust jelez, és változatlanul hagyja a tartalmat. A kliens ezután megmutathatja az eltérést, de nem növelheti vakon az elvárt számot újabb írás kedvéért.

A JSON-összehasonlító használható a kiinduló, a szerkesztett és az aktuálisan visszaolvasott mezők vizsgálatára. A döntéshez a tartalom kell, a státuszkód önmagában kevés.

A HTTP-módszer nem helyettesíti az alkalmazási szerződést

A HTTP szemantikáját leíró szabvány megkülönbözteti a biztonságos és az idempotens módszereket. Az idempotencia az ismétlés kívánt szerveroldali hatásáról szól; nem jelenti azt, hogy minden válasz vagy naplóbejegyzés azonos lesz.

Egy POST-létrehozás ismételhetőségét az alkalmazásnak külön biztosítania kell, például dokumentált idempotenciakulccsal vagy egyediség- és revíziófeltétellel. Ilyen támogatást nem szabad feltételezni pusztán azért, mert a végpont neve ismerős.

A HTTP-fejléc-elemző a bemásolt válasz értelmezésében segíthet. Hitelesítési kulcsot azonban ne másolj bele nyilvános jelentésbe vagy képernyőképbe. A naplóban csak a szükséges, nem titkos hibakód és műveletazonosító maradjon.

Az import haladását bejegyzésenként őrizd meg

Ötven cikkből például húsz visszaellenőrzötten mentett, egynek bizonytalan a kimenete, huszonkilenc pedig még el sem indult. Ez három külön állapot. Az egész csomagot „sikertelennek” nevezni elveszíti a fontos részleteket.

Folytatáskor először a bizonytalan cikket egyeztesd. A már igazolt húsz bejegyzést ne hozd létre újra. A hátralévő műveletekhez ugyanazok az előkészített azonosítók és változatlan tartalmi ellenőrzőösszegek tartozzanak. A közzététel külön lépés is lehet a vázlatok sikeres ellenőrzése után.

A „még nem található” válasz mellett is futhat az első mentés

Egy külön időrendben a kliens elküldi a létrehozást, majd időtúllépést kap. Az azonnali visszaolvasás még nem talál cikket, az eredeti szerverfolyamat azonban egy pillanattal később befejezi a mentést. A korábbi „nem található” válasz önmagában ezért nem bizonyítja, hogy az első kérés már biztosan nem hajt végre írást. Elosztott rendszerben az olvasási út frissessége is számíthat.

A mintában a védelem az, hogy az azonosító egyedi, és a szerver a 0 elvárt revíziót a létrehozással egyetlen oszthatatlan műveletként ellenőrzi. Ha az első kérés létrehozta az 1. revíziót, a második, ugyanerre a névre és 0 revízióra érkező létrehozás már nem teljesítheti a feltételt. Az eredmény legfeljebb egy létrehozott cikk. A konfliktus után ismét vissza kell olvasni és egyeztetni a tartalmat.

Kliensoldali „előbb megnézem, aztán létrehozom” ellenőrzés szerveroldali egyediség nélkül kevés: két kérés ugyanazt a még üres állapotot láthatja. Hasonló védelmet dokumentált idempotenciakulcs adhat, de annak érvényességi idejét és az eltérő tartalmú újraküldés szabályát is ismerni kell. Az HTTP-szabvány feltételes kérései ehhez kapcsolódó mechanizmusokat írnak le; a saját végpont tényleges támogatása külön ellenőrzendő.

Az ötvenes import példájában, ha a bizonytalan huszonegyedik mentést sikeresen visszaegyeztetted, az állapot 21 igazolt és 29 el nem indított cikk. Ha az eredeti kérés lezárulta és az állapot alapján igazoltan nem történt mentés, a 20 kész mellé 30 még elvégzendő kerül. Ezt az átmenetet a konkrét cikkhez naplózd. A teljes csomag újraindítása egyik esetben sem ad pontosabb állapotot.

Gyakori kérdések

A 401 válasz bizonyítja, hogy a feltöltés működik?

Csak a hitelesítés nélküli vagy elutasított kérés állapotát jelzi. Sikeres mentést a hitelesített írás és az utána végzett visszaolvasás igazol.

Időtúllépés után töröljem a félkésznek gondolt cikket?

Előbb olvasd vissza. Lehet, hogy a mentés teljesen sikerült; bizonyíték nélkül a törlés adatvesztést okozhat.

Konfliktusnál automatikusan a saját változatom legyen az újabb?

Ne írj felül közben módosított tartalmat vakon. Az eltéréseket és a tényleges revíziót össze kell egyeztetni.

Záró tudáspróba

Válassz kérdésenként egy választ. A megoldások ellenőrzése után minden helyes válaszért 1 pontot adj magadnak; a hibás, kihagyott vagy több válasszal megjelölt kérdés 0 pont. Összesen 0–3 pont szerezhető.

1. Időtúllépés után az első visszaolvasás még nem talál cikket. Mi következik ebből?

  • A) Az eredeti kérés biztosan már nem menthet.
  • B) Csak az, hogy azon az olvasási úton akkor még nem volt látható; az eredeti kérés állapotát és az ismétlés szerződését is tisztázni kell.
  • C) Biztonságos új, véletlen azonosítóval létrehozni ugyanazt a cikket.

2. Az első kérés az 1. revíziót már létrehozta. Mit tegyen a szerver a második, azonos nevű, 0 elvárt revíziós létrehozással?

  • A) Automatikusan adjon neki új nevet.
  • B) Írja felül az első cikket.
  • C) Utasítsa el a már nem teljesülő létrehozási feltételt.

3. 20 cikk igazolt, egy bizonytalan, 29 még nem indult. A bizonytalan mentést sikeresen igazolod. Mi az új állapot?

  • A) 21 igazolt és 29 még nem indult.
  • B) 20 igazolt és 30 újra feltöltendő.
  • C) Mind az 50-et elölről kell kezdeni.

Megoldások és pontszám

1. B. A szerverfolyamat később is befejezheti a korábban elküldött írást. A feltételes létrehozás vagy idempotenciakulcs szerveroldali garanciája ezért fontos.

2. C. A 0 azt feltételezi, hogy még nincs korábbi bejegyzés. A szervernek ezt a létrehozással együtt kell ellenőriznie, majd konfliktus után tartalmi visszaegyeztetés következik.

3. A. A bizonytalan egy cikk az igazolt állapotba kerül. A korábban kész húsz változatlanul kész, a hátralévő 29 még nem indult.

3 pont: A bizonytalan válaszból és a szerveroldali feltételből is helyes következő lépést választottál. Saját importnál a kérés és a cikk állapotát külön rögzítsd.

2 pont: Az 1. kérdéshez a későn befejeződő mentés időrendjét, a 2.-hoz az oszthatatlan revíziófeltételt, a 3.-hoz az ötvenes állapottáblát nézd át.

0–1 pont: Írd fel, mit tudsz biztosan a kérésről és a szerverállapotról. Ezután a dokumentált egyediség- vagy idempotenciagarancia alapján döntsd el, mikor küldhető újra a művelet.

További cikkek

Kapcsolódó olvasnivalók

Gyorskereső

Kalkulátorok és útmutatók keresése

↑↓ választásEnter megnyitásEsc bezárás