Come faccio a scegliere un codice di stato HTTP nell'API REST per "Non ancora pronto, riprova più tardi"? [chiuso]


152

Sto sviluppando un'API RESTful in cui http://server/thingyapi/thingyblob/1234restituisce il file (noto anche come "blob") associato a cosa # 1234 da scaricare. Ma è possibile che la richiesta venga effettuata in un momento in cui il file non esiste nel server ma sicuramente sarà disponibile in un secondo momento. C'è un processo batch nel server che genera tutti i BLOB per tutte le cose. Thingy 1234 esiste già e i suoi dati, oltre al BLOB, sono già disponibili. Il server non deve ancora generare il blob di cosa 1234.

Non voglio restituire 404; questo è per cose che non esistono. Questo è qualcosa che esiste, ma il suo BLOB non è stato ancora generato. Piace un video di YouTube che sta "elaborando". Non penso che neanche i codici di reindirizzamento sarebbero corretti; non c'è nessun "altro" URL da provare.

Qual è il codice di stato HTTP corretto da restituire in questo caso?



7
In primo luogo, se cosa 1234 non ha ancora alcuna rappresentazione in grado di ottenere, in che senso esiste come risorsa (dal punto di vista del cliente)? Il fatto che, all'interno del server, vi sia un lavoro in coda per creare 1234, non sembra implicare l'esistenza della risorsa 1234. Secondo, dove ha ricevuto l'URI il client ... / thingyblob / 1234? Il server probabilmente non avrebbe dovuto fornire tale URI al client fino a quando la risorsa non fosse effettivamente in grado di ottenere.
Andy Dennie,

1
Un oggetto ha altre proprietà che vale la pena ottenere oltre al BLOB. È solo il BLOB che richiede tempo per generare. Il client ottiene quelli, ad esempio, server / thingyapi / thingy / 1234
JCCyC

10
Lo standard HTTP fornisce indicazioni su quali codici di stato utilizzare per quali situazioni. Pertanto, questa domanda non si basa principalmente sull'opinione pubblica .
Raedwald,

2
Che ne dici di 204"Nessun contenuto"? È indica che il server ha elaborato correttamente la richiesta e non sta restituendo alcun contenuto [al momento].
Timo,

Risposte:


77

Io suggerisco 202 - Accepted. Dalla documentazione :

La richiesta è stata accettata per l'elaborazione, ma l'elaborazione non è stata completata. [...] Il suo scopo è consentire a un server di accettare una richiesta per qualche altro processo (forse un processo orientato al batch che viene eseguito solo una volta al giorno)


62
-1: Ciò avrebbe senso per la richiesta che avvia il processo che alla fine crea "cosa # 1234", ma non per la richiesta GET emessa successivamente per "cosa # 1234" stesso. In particolare, un 202 suggerisce che, a seguito della richiesta GET, il servizio invierà i dati per "cosa # 1234" in un secondo momento. Questo semplicemente non è corretto.
Sam Harwell,

7
Dice anche: "L'entità restituita con questa risposta DOVREBBE includere un'indicazione dello stato corrente della richiesta e un puntatore a un monitor di stato o una stima di quando l'utente può aspettarsi che la richiesta venga soddisfatta.", Quindi questo sarebbe un buon modo per far sapere al client che il BLOB non è ancora pronto e un modo per scoprire quando è pronto.
Remy Lebeau,

3
Direi che "accettato per l'elaborazione" indica che stai salvando la richiesta per essere seguito in seguito. Se viene appena ignorato, è necessario restituire un codice 4xx o 5xx per indicare al client che potrebbero voler riprovare.
Luca,

3
102 (elaborazione) sembra anche una scelta ragionevole a volte anche se è nelle specifiche webdav.
Akostadinov,

2
Non posso essere più in disaccordo con questa risposta. Il server non sta restituendo nulla o sta pianificando (non sta eseguendo alcuna elaborazione a causa di questa richiesta, cosa che comunque non dovrebbe ottenere un GET). Come tale, la risorsa non è in qualche modo disponibile per il cliente. Questo dovrebbe essere trattato come un errore, quindi nessun codice 2XX è appropriato. Qualcosa nello spazio 4XX o 5XX. La richiesta non è stata "accettata per l'elaborazione" , la richiesta è in pratica scartata
Adam,

52

Il "problema", come è, è sul lato server: il client ha formulato una richiesta ben formata, ma il server non può soddisfarla. Quindi sono propenso a un "Errore del server", codice di stato 5xx.

Quoth RFC 7231 (l'attuale standard HTTP, enfasi aggiunta):

La classe 5xx (errore del server) del codice di stato indica che il server è consapevole di aver commesso un errore o non è in grado di eseguire il metodo richiesto . Tranne quando risponde a una richiesta HEAD, il server DOVREBBE inviare una rappresentazione contenente una spiegazione della situazione di errore e se si tratta di una condizione temporanea o permanente.

Nota

  • "errato o incapace di eseguire la richiesta": nonostante il titolo di "Errore del server", non sono solo errori del server.
  • " temporaneo o permanente": questi codici sono adatti a risorse temporaneamente non disponibili, come la tua.

Tra i codici disponibili, direi 503, "Servizio non disponibile" era la soluzione migliore:

Il codice di stato 503 (servizio non disponibile) indica che il server non è attualmente in grado di gestire la richiesta a causa di un sovraccarico temporaneo o di una manutenzione programmata, che sarà probabilmente alleviata dopo un certo ritardo. Il server PUO 'inviare un campo di intestazione Retry-After ... per suggerire un adeguato periodo di tempo prima che il client attenda prima di ritentare la richiesta.

Nota:

  • "probabilmente sarà alleviato dopo qualche ritardo": vero per il tuo caso.
  • "sovraccarico temporaneo": non pedante per il tuo caso. Ma, si potrebbe sostenere, se il tuo server fosse molto più veloce, l'elaborazione in batch sarebbe già stata eseguita quando il client ha effettuato la richiesta, quindi è una sorta di "sovraccarico": il client chiede risorse più velocemente di quanto il server possa fare loro disponibili.
  • Riprovare è adatto al tuo servizio, quindi la tua risposta dovrebbe includere un Retry-Aftervalore. È possibile fornire come valore il tempo di completamento stimato della successiva esecuzione del processo batch o l'intervallo di esecuzione del processo batch.

La definizione del proprio codice di stato 5xx (591, ad esempio), sebbene consentito , avrebbe la semantica errata:

un client DEVE comprendere la classe di qualsiasi codice di stato, come indicato dalla prima cifra, e trattare un codice di stato non riconosciuto come equivalente al codice di stato x00 di quella classe

I client considererebbero il proprio codice di stato come 500, "Errore interno del server" , il che non sarebbe corretto.


2
Non riesco a vedere come sia meglio di 202: benramsey.com/blog/2008/04/…
JCCyC

4
@JCCyC il tuo blog è un buon caso per restituire un 202 in risposta a una richiesta di creare qualcosa (un POST o PUT). La domanda sembra porsi su cosa restituire per ottenere un GET.
Raedwald,

@JCCyC potrebbe essere visto come una diversa sfumatura di non-prontezza: immagina un ajax a quella risorsa, preferisci 202 come stato di successo o 503 come stato di errore? in modo da poter vedere quale senso si preferisce implicitamente nel contesto della reazione del vostro app per la risposta
rloth

mi piace anche l'aspetto pratico di "Retry-After" che va bene con qualcosa di "non pronto"
rloth

1
NB: "Riprova-Dopo" può anche andare con 307 - TEMPORARY REDIRECTche è buono se si vuole lato client forza di aspettare altrove in tutta ressource viene "preparata"
rloth

28

Penso che 423 - Locked possa essere utilizzato per questo scopo:

Il codice di stato 423 (bloccato) indica che la risorsa di origine o destinazione di un metodo è bloccata. Questa risposta DOVREBBE contenere un codice precondizione o postcondizione appropriato, come "lock-token-submit" o "no-contrasting-lock".


1
Risposta eccellente! Mi chiedo perché non abbia più voti.
lex82,

10
Forse perché è un codice HTTP WebDAV?
Stephan L,

1
Da akka-http c'è StatusCode RetryWith = reg (c (449) ("Riprova con", "La richiesta dovrebbe essere ritentata dopo aver fatto l'azione appropriata.")) Dove l'azione sarebbe attesa e riprovata
ozma

2
In molti modi sono d'accordo con questo. Ho una situazione simile (nel mio caso la ricerca da un indice che potrebbe non essere ancora popolato). Semanticamente, penso che sia corretto. Tuttavia, la RFC per 423 afferma "Questa risposta DOVREBBE contenere un prerequisito o un codice postcondizione appropriati, come" lock-token-submit "o" no-contrasting-lock "." Non sono sicuro di come applicarlo qui. E personalmente andrei con 409 Conflict, ma questo è stato ridimensionato senza commenti - non sai perché?
Adam,

22

Non voglio restituire 404; questo è per cose che non esistono.

L'URL non corrisponde a una richiesta per una cosa.

http://server/thingyapi/thingyblob/1234

Il client richiede una cosa, che non esiste. Se esistesse, lo daresti a loro.

404.


1
Sono contento che qualcuno l'abbia detto! Non riesco a credere che ci siano così tante persone che pensano che 503sia una risposta appropriata. Per non parlare di alcuni degli altri strani suggerimenti.
Jason Desrosiers,

Anche se concordo sul fatto che un 404 è la risposta più appropriata qui, non risponde alla domanda del PO su come indicare quando la cosa è disponibile :-). Penso che il campo Retry-After sembri il miglior candidato, ma può essere utilizzato ufficialmente solo per i codici 503 e 3xx. @Jason: penso che spieghi alcuni degli strani suggerimenti.
Ron Deijkers,

Penso che questa sia la risposta migliore. Puoi restituire un corpo in una risposta 404. Il corpo potrebbe indicare che la cosa sarà disponibile in un secondo momento. Oppure usa anche l'intestazione Retry-After. Lo standard deve essere allungato un po 'qui perché non copre bene questo caso.
WW.

4
Le persone sono diventate troppo acclimatate alla pagina del significato 404, non trovando che non possono dissociarsi logicamente nel contesto di un'API.
The Muffin Man

1
Questo è mooooolto 404. Thingyblob non esiste ancora, o mai .. Per http è irrilevante se sarà mai disponibile. Al momento non esiste, e il suo 404. Quando sarà disponibile è un altro problema, che può essere risolto spingendo un messaggio dal server al client e dicendo qualcosa: 1234 disponibile. Esegui di nuovo get and voila ..
100r

21

Un'altra opzione: 503 - Service Unavailable.


5
Secondo W3C non è ciò che si desidera dire al client (anche se significa "tornare di nuovo" in qualche modo): "Il server non è attualmente in grado di gestire la richiesta a causa di un sovraccarico temporaneo o della manutenzione del server. L'implicazione è che questa è una condizione temporanea che verrà alleviata dopo un certo ritardo. Se noto, la lunghezza del ritardo PUO 'essere indicata in un'intestazione Retry-After. Se non viene fornito nessun Retry-After, il client DOVREBBE gestire la risposta come farebbe per un 500 risposta ".
Skalee,

4
Il servizio non è disponibile, il servizio è disponibile ma l'elaborazione non è completa. Quindi 503 probabilmente non è una buona idea.
Ishtiaque Khan,

17

Poiché la tua risorsa non è pronta, probabilmente sai quando (approssimativamente) sarà disponibile e quando il cliente potrebbe ritentare la sua richiesta. Ciò significa che potresti voler utilizzare l' intestazione Retry-After . Questa intestazione è valida con 503 (servizio non disponibile), il che significa che l'intero sito è inattivo per manutenzione e 3xx (reindirizzamento).

A mio avviso 302 (Trovato) con intestazione Retry-After sarebbe l'opzione migliore, ma non sono sicuro che il campo Posizione dell'intestazione della risposta possa essere uguale all'URL della richiesta. Si tratta di reindirizzamento circolare, comunque.


3
Anche se è permesso, se il client non ha implementato il supporto per l'intestazione Retry-After, un reindirizzamento 3xx sulla stessa pagina potrebbe finire con un 503 ... (facoltativamente con un header Retry-After ovviamente)
Ron Deijkers

1
Retry-After è valido anche con HTTP 429 "Troppe richieste", aggiunto da RFC 6585 (aprile 2012). Questo potrebbe essere appropriato se il motivo per cui la risorsa non è ancora pronta è che il client ha dato al server troppo lavoro da fare.
Silas S. Brown,

8

409 Conflitto

Indica che la richiesta non può essere elaborata a causa di un conflitto nella richiesta, ad esempio un conflitto di modifica nel caso di più aggiornamenti. [Fonte Wikipedia.]

Questo potrebbe essere appropriato.

Se non riesci a soddisfare la richiesta restituendo i dati, non è un successo. Penso che 202 suggerisca che il server ha messo in coda la richiesta e soddisferà la richiesta in seguito. Ma nel tuo caso, la richiesta è per i dati ora e non è riuscita. Se riprovi più tardi, si tratta di una richiesta diversa.

Penso che tu abbia un conflitto .. vuoi i dati .. ma è in fase di modifica / aggiornamento. Questo sarebbe anche il caso se Thingy1234 fosse già esistito e fosse stato scaricato con successo in precedenza, ma ora era in procinto di essere modificato non era disponibile mentre era in corso la modifica.


2
Non sono sicuro del motivo per cui questo è stato votato verso il basso. Sembra la risposta giusta per me. Dall'RFC: "Il codice di stato 409 (Conflitto) indica che non è stato possibile completare la richiesta a causa di un conflitto con lo stato corrente della risorsa di destinazione. Questo codice viene utilizzato in situazioni in cui l'utente potrebbe essere in grado di risolvere il conflitto e reinvia la richiesta. "Hai richiesto una risorsa che il server non può restituire perché il server sta aggiornando tale risorsa, ovvero a causa dello stato corrente della risorsa. Il cliente può risolvere questo problema aspettando e reinoltrando
Adam

1
@Adam Penso che l'implicazione in "l'utente potrebbe essere in grado di risolvere il conflitto" è che qualcosa sulla reinvio sarebbe diverso, oltre alla semplice attesa.
Sviluppatore olistico,

3

501 - Non implementato

Esattamente come suona. Una funzionalità che non è ancora stata implementata, ma implica la disponibilità futura.

Ecco un link a un riepilogo degli errori 5xx .


4
Per questa domanda sembra che la funzione stessa esista, ma l'articolo richiesto non lo è.
Luca,

La descrizione di @Luke 501 dal link nella mia risposta, '... manca della capacità di soddisfare la richiesta. Di solito questo implica disponibilità future '. Ciò soddisfa esattamente ciò che l'OP stava chiedendo. Indipendentemente dal fatto che i dati siano presenti o meno sui suoi server o DB. Il risultato finale è che per ora non è accessibile tramite l'API. Pertanto l'API non è in grado di soddisfare la richiesta, ma vorrebbe sottintendere che sarà disponibile in futuro tramite il codice http.
Dan,
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.