È sbagliato restituire 202 "Accettato" in risposta a HTTP GET?


89

Ho una serie di risorse le cui rappresentazioni vengono create pigramente. Il calcolo per costruire queste rappresentazioni può richiedere da pochi millisecondi a poche ore, a seconda del carico del server, della risorsa specifica e della fase lunare.

La prima richiesta GET ricevuta per la risorsa avvia il calcolo sul server. Se il calcolo viene completato entro pochi secondi, viene restituita la rappresentazione calcolata. In caso contrario, viene restituito un codice di stato 202 "Accettato" e il client deve eseguire il polling della risorsa finché non è disponibile la rappresentazione finale.

La ragione di questo comportamento è la seguente: se un risultato è disponibile entro pochi secondi, deve essere recuperato il prima possibile; altrimenti, quando diventa disponibile non è importante.

A causa della memoria limitata e dell'enorme volume di richieste, né NIO né il polling lungo sono un'opzione ( cioè non riesco a mantenere aperte quasi abbastanza connessioni, né posso nemmeno adattare tutte le richieste in memoria; una volta "pochi secondi" sono passate, persisto le richieste in eccesso). Allo stesso modo, le limitazioni del client sono tali che non possono invece gestire un callback di completamento. Infine, tieni presente che non sono interessato a creare una risorsa "di fabbrica" ​​a cui eseguire il POST, poiché i viaggi di andata e ritorno extra significano che falliamo il vincolo in tempo reale a tratti più di quanto si desideri (inoltre, è una complessità extra; inoltre, questa è una risorsa che potrebbe trarre vantaggio dalla memorizzazione nella cache).

Immagino che ci sia qualche controversia sulla restituzione di un codice di stato 202 "Accettato" in risposta a una richiesta GET, visto che non l'ho mai visto in pratica e il suo utilizzo più intuitivo è in risposta a metodi non sicuri, ma non l'ho mai visto trovato qualcosa di specificamente scoraggiante. Inoltre, non sto preservando sia la sicurezza che l'idempotenza?

Allora, cosa ne pensa la gente di questo approccio?

EDIT : dovrei menzionare che questo è per una cosiddetta API web aziendale, non per i browser.


2
Personalmente penso che sia buono, è esattamente la definizione di a 202. Il fatto che sia usato raramente nella pratica è IMHO di più perché pochi sviluppatori web si preoccupano dei codici di stato corretti in quanto sono più abituati all'interazione browser / user-agent, nel qual caso a non 202fornisce loro indizi visibili (dai loro un 200e sono felici. ..).
Wrikken

1
@ user359996, basta usare 200. 202è quello che dovrebbe essere, ma in pratica le persone non si aspettano 202.
Pacerier

ha bisogno di un ETA perché un 200 sia utile nella pratica.
Rob il

Risposte:


66

Se è per un'API ben definita e documentata, 202suona esattamente per quello che sta succedendo.

Se fosse per Internet pubblico, sarei troppo preoccupato per la compatibilità del client. Ne ho visti così tanti if (status == 200)hard-coded .... In tal caso, restituirei un file 200.

Inoltre, l' RFC non indica che l'utilizzo di 202 per una richiesta GET sia sbagliato, mentre fa chiare distinzioni in altre descrizioni del codice (ad esempio 200).

La richiesta è stata accettata per l'elaborazione, ma l'elaborazione non è stata completata.


15

Lo abbiamo fatto per un'applicazione recente, un client (applicazione personalizzata, non un browser) ha inviato una query con POST e il server restituiva 202 con un URI al "lavoro" pubblicato: il client userebbe quell'URI per eseguire il polling per il risultato - questo sembra adattarsi perfettamente a ciò che veniva fatto.

La cosa più importante qui è comunque documentare come funziona il tuo servizio / API e cosa significa una risposta di 202.


+1 Grazie per il tuo commento. Buon punto sulla documentazione. Ma per favore nota le modifiche per chiarire la mia domanda (cerca "fabbrica").
user359996

Bene, puoi omettere quell'URI nella risposta se vuoi solo interrogare lo stesso URI inizialmente richiesto. (Documenta solo come dovrebbe funzionare :-))
nn

Buona idea, ma ricorda che voglio la memorizzazione nella cache, quindi nessun POST. Inoltre, l'URI specifica la risorsa, non un metodo. Sto adottando un approccio RESTful, piuttosto che RPC (scusate, un altro vincolo non specificato - il mio male).
user359996

Per essere precisi, con "RESTful" intendo in realtà "orientato alle risorse", che tecnicamente è un po 'più di quanto specificato dai vincoli REST.
user359996

12

Da quello che posso ricordare - GET dovrebbe restituire una risorsa senza modificare il server. Forse l'attività verrà registrata o cosa hai, ma la richiesta dovrebbe essere riesaminabile con lo stesso risultato.

POST d'altra parte è una richiesta per cambiare lo stato di qualcosa sul server. Inserisci un record, elimina un record, esegui un lavoro, qualcosa del genere. 202 sarebbe appropriato per un POST restituito ma non completato, ma non realmente una richiesta GET.

È tutto molto puritano e non ben praticato in natura, quindi probabilmente sei al sicuro restituendo 202. GET dovrebbe restituire 200. POST può restituire 200 se è finito o 202 se non è finito.

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


4
Ottimo pensiero ma non sono sicuro che si applichi qui: da quello che dice l'OP, questa sembra essere una richiesta GET corretta (in quanto non cambia nulla sul server), ci vuole solo più tempo per calcolare e in quel caso, deve essere recuperato in un altro momento. Forse l'OP può dare un commento autorevole. È per un'API quindi va bene essere "puritano" per un'interfaccia pulita
Pekka

Oh, touche pekka. Hai ragione, GET è la strada da percorrere. E non penso che HTTP spc abbia davvero preso in considerazione i GET che non sono pronti. Quindi potrebbe andare in entrambi i modi
Dlongnecker

7
Commento autorevole (ora irrilevante): Sì, lo considero idempotente. La risorsa non viene né modificata né creata, piuttosto la sua rappresentazione non è stata ancora calcolata.
user359996

1
Dove dice questo? Inoltre, se restituisco 200, il cliente dovrebbe aspettarsi che sia stata restituita una rappresentazione, ma non è stato così.
user359996

1
Lo porto indietro. 202 non corrisponde solo a GET o POST a quanto pare. Solo la mentalità in cui ero quando ho guardato il protocollo mi ha fatto pensare che il 202 esisteva solo per le richieste GET. 202 dovrebbe andare bene per i tuoi scopi.
Dlongnecker

0

Nel caso di una risorsa che dovrebbe avere una rappresentazione di un'entità che è chiaramente specificata da un ID (al contrario di una risorsa "fabbrica", come descritto nella domanda), consiglio di rimanere con il metodo GET e, in un situazione in cui l'entità / rappresentazione non è disponibile a causa della creazione pigra o di qualsiasi altra situazione temporanea, utilizzare il codice di risposta 503 Servizio non disponibile che è più appropriato ed è stato effettivamente progettato per situazioni come questa.

Il motivo di ciò può essere trovato nelle RFC per HTTP stesso (verificare la descrizione del codice di risposta 503), così come in numerose altre risorse.

Confronta con il codice di stato HTTP per le pagine temporaneamente non disponibili . Sebbene questa domanda riguardi un caso d'uso diverso, in realtà si riferisce alla stessa identica funzionalità di HTTP.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.