Este greșit să se returneze 202 „Acceptat” ca răspuns la HTTP GET? (Programare, Coduri De Stare Http, Http Get)

user359996 a intrebat.
a intrebat.

Am un set de resurse ale căror reprezentări sunt create în mod leneș. Calculul pentru a construi aceste reprezentări poate dura de la câteva milisecunde până la câteva ore, în funcție de sarcina serverului, de resursa specifică și de faza lunii.

Prima cerere GET primită pentru o resursă începe calculul pe server. În cazul în care calculul se finalizează în câteva secunde, este returnată reprezentarea calculată. În caz contrar, se returnează un cod de stare 202 „Accepted”, iar clientul trebuie să cerceteze resursa până când este disponibilă reprezentarea finală.

Motivul pentru acest comportament este următorul: În cazul în care un rezultat este disponibil în câteva secunde, acesta trebuie recuperat cât mai curând posibil; în caz contrar, momentul în care este disponibil nu este important.

Din cauza memoriei limitate și a volumului mare de cereri, nici NIO, nici interogarea îndelungată nu reprezintă o opțiune (de ex. nu pot menține deschise nici pe departe suficiente conexiuni și nici măcar nu pot să încap toate cererile în memorie; odată ce au trecut „câteva secunde”, persistă cererile în exces). De asemenea, limitările clienților sunt de așa natură încât nu pot gestiona, în schimb, un callback de finalizare. În cele din urmă, rețineți că nu mă interesează să creez o resursă „fabrică” la care să se facă POST-uri, deoarece călătoriile suplimentare înseamnă că nu reușim să respectăm constrângerea de timp real la bucată mai mult decât se dorește (în plus, este o complexitate suplimentară; de asemenea, aceasta este o resursă care ar beneficia de caching).

Îmi imaginez că există unele controverse cu privire la returnarea unui cod de stare 202 „Accepted” ca răspuns la o cerere GET, având în vedere că nu am văzut niciodată acest lucru în practică, iar utilizarea sa cea mai intuitivă este ca răspuns la metode nesigure, dar nu am găsit niciodată nimic care să descurajeze în mod special acest lucru. În plus, nu păstrez atât siguranța, cât și idempotența?

Deci, ce părere au oamenii despre această abordare?

EDITARE: Ar trebui să menționez că acest lucru este pentru un așa-numit API web de afaceri – nu pentru browsere.

Comentarii

  • Eu personal cred că este o idee bună, este exact definiția unei 202. Faptul că este rar folosit în practică se datorează mai degrabă faptului că puțini dezvoltatori web se preocupă de codurile de stare corespunzătoare, deoarece sunt mai mult obișnuiți cu interacțiunea dintre browser și user-agent, caz în care a 202 nu le oferă niciun indiciu vizibil (dați-le un 200 și ei sunt fericiți…). –  > Por Wrikken.
  • @user359996, folosiți doar 200. 202 este ceea ce este ar trebui să să fie, dar în practică oamenii nu se așteaptă ca 202. –  > Por Pacerier.
  • este nevoie de o ETA pentru ca un 200 să fie util în practică, totuși. –  > Por Rob.
4 răspunsuri
Pekka

Dacă este pentru un API bine definit și -documentat, 202 sună exact corect pentru ceea ce se întâmplă.

Dacă este pentru internetul public, aș fi prea îngrijorat de compatibilitatea clienților. Am văzut atât de multe if (status == 200) hard-coded…. În acest caz, aș returna un 200.

De asemenea, se poate aplica RFC nu indică faptul că utilizarea 202 pentru o cerere GET este greșită, în timp ce face distincții clare în alte descrieri de coduri (de exemplu, 200).

Cererea a fost acceptată pentru procesare, dar procesarea nu a fost finalizată.

nos

Am făcut acest lucru pentru o aplicație recentă, un client (o aplicație personalizată, nu un browser) a postat o interogare, iar serverul a returnat 202 cu un URI la „jobul” postat – clientul a folosit acel URI pentru a cere rezultatul – acest lucru pare să se potrivească perfect cu ceea ce se făcea.

Cel mai important lucru aici este, oricum, să documentați modul în care funcționează serviciul/API-ul dumneavoastră și ce înseamnă un răspuns 202.

Comentarii

  • +1 Vă mulțumim pentru comentariu. Bună observație cu privire la documentare. Dar vă rugăm să rețineți modificările de clarificare la întrebarea mea (căutați „factory”). –  > Por utilizator359996.
  • Ei bine, puteți omite acel URI în răspuns dacă doriți doar să sondați același URI pe care l-ați solicitat inițial. (Doar documentați modul în care ar trebui să funcționeze 🙂 ) –  > Por nos.
  • Bună idee, dar nu uitați că vreau caching, așa că nu POST. În plus, URI-ul specifică resursa, nu o metodă. Am adoptat o abordare RESTful, mai degrabă decât RPC (scuze, o altă constrângere nespecificată – greșeala mea). –  > Por user359996.
  • Pentru a fi precis, prin „RESTful”, vreau să spun de fapt „orientat spre resurse”, ceea ce, din punct de vedere tehnic, este puțin mai mult decât este specificat de constrângerile REST. –  > Por user359996.
  • Acest lucru este susținut și de „1.10 Cum să utilizați POST pentru sarcini asincrone” din cartea „RESTful Web Services Cookbook” de Subbu Allamraju –  > Por koppor.
Dlongnecker

Din câte îmi amintesc – GET ar trebui să returneze o resursă fără a modifica serverul. Poate că activitatea va fi înregistrată sau ce ai, dar cererea ar trebui să poată fi reluată cu același rezultat.

POST, pe de altă parte, este o cerere pentru a schimba starea a ceva pe server. Introducerea unei înregistrări, ștergerea unei înregistrări, rularea unei activități, ceva de genul acesta. 202 ar fi adecvat pentru un POST care s-a întors, dar nu este finalizat, dar nu este chiar o cerere GET.

Totul este foarte puritan și nu este bine practicat în sălbăticie, așa că probabil că ești în siguranță întorcând 202. GET ar trebui să returneze 200. POST poate returna 200 dacă s-a terminat sau 202 dacă nu s-a terminat.

http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

Comentarii

  • Foarte bine gândit, dar nu sunt sigur că se aplică aici: Din ceea ce spune OP, aceasta pare a fi o cerere GET corectă (în sensul că nu schimbă nimic pe server), doar că durează mai mult să se calculeze și, în acest caz, trebuie să fie recuperată în alt moment. Poate că OP poate da un comentariu autorizat. Este pentru un API, așa că este în regulă să fii „puritan” de dragul unei interfețe curate…  > Por Pekka.
  • Oh, touche pekka. Ai dreptate, GET este calea de urmat. Și nu cred că HTTP spc a luat în considerare cu adevărat GET-urile care nu sunt pregătite. Așa că ar putea merge în ambele direcții –  > Por Dlongnecker.
  • (Acum irelevant) comentariu autoritar: Da, văd acest lucru ca fiind idempotent. resursă nu este nici modificată, nici creată, ci mai degrabă este reprezentare nu a fost încă calculată. –  > Por user359996.
  • Unde se spune asta? De asemenea, dacă returnez 200, clientul ar trebui să se aștepte să fie returnată o reprezentare, dar nu este așa. –  > Por user359996.
  • Îmi retrag afirmația. 202 nu corespunde doar la GET sau POST se pare. Pur și simplu mentalitatea în care mă aflam când m-am uitat la protocol m-a făcut să cred că 202 există doar pentru cereri GET. 202 ar trebui să fie în regulă pentru scopurile tale. –  > Por Dlongnecker.
Hermes

În cazul unei resurse care ar trebui să aibă o reprezentare a unei entități care este clar specificată printr-un ID (spre deosebire de o resursă „fabrică”, așa cum este descrisă în întrebare), vă recomand să rămâneți la metoda GET și, în situația în care entitatea/reprezentarea nu este disponibilă din cauza creării leneșe sau a oricărei alte situații temporare, să folosiți codul de răspuns 503 Service Unavailable, care este mai adecvat și a fost de fapt conceput pentru situații ca aceasta.

Raționamentul pentru acest lucru poate fi găsit în RFC-urile pentru HTTP (vă rugăm să verificați descrierea codului de răspuns 503), precum și în numeroase alte resurse.

Vă rugăm să comparați cu codul de stare HTTP pentru paginile temporar indisponibile. Deși această întrebare se referă la un caz de utilizare diferit, ea se referă de fapt la exact aceeași caracteristică a HTTP.