105

Sto sviluppando un'API RESTful in cui http://server/thingyapi/thingyblob/1234 restituisce il file (aka "blob") associato a thingy # 1234 da scaricare. Ma può darsi che la richiesta venga fatta in un momento in cui il file non esiste nel server ma sicuramente lo sarà disponibile in un momento successivo a. 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 è ancora riuscito a generare il blob di thingy 1234.Come faccio a scegliere un codice di stato HTTP nell'API REST per "Non ancora pronto, riprovare più tardi"?

Non voglio restituire 404; questo è per cose che non esistono. Questo è un coso che esiste, ma il suo blob non è ancora stato generato. Un po 'come un video di YouTube che "elabora". Non penso che i codici di reindirizzamento sarebbero appropriati; non c'è nessun "altro" URL da provare.

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

+1

[in qualche modo correlato] (http://stackoverflow.com/questions/7730199/best-practice-for-implementing-long-running-searches-with-rest/7730452#7730452) –

+5

In primo luogo, se thingy 1234 non ha ancora alcuna rappresentazione GET-in che senso esiste come risorsa (dal punto di vista del cliente)? Il fatto che, interno al server, ci sia un lavoro in coda per creare 1234, non sembra implicare che la risorsa 1234 esista. Secondo, dove il client ha ottenuto l'URI .../thingyblob/1234? Probabilmente il server non avrebbe dovuto fornire quell'URI al client finché la risorsa non fosse effettivamente GET-capable. –

+1

Una cosa ha altre proprietà che vale la pena di ottenere oltre al blob. È solo il blob che richiede tempo per generare. Il client ottiene, ad esempio, http: // server/thingyapi/thingy/1234 – JCCyC

risposta

52

Suggerisco 202 - Accepted. Da documentation:

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

+32

-1: Questo avrebbe senso per la richiesta che avvia il processo che alla fine crea "thingy # 1234", ma non per la richiesta GET emessa successivamente per "thingy # 1234" stesso. In particolare, un 202 suggerisce che, come risultato della richiesta GET, il servizio invierà i dati per "thingy # 1234" in un secondo momento. Questo semplicemente non è corretto. –

+0

La documentazione afferma chiaramente: "Alla richiesta potrebbe o non potrebbe essere eventualmente applicata", quindi non vi è alcun obbligo per GET di inviare i dati in un secondo momento se 202 viene segnalato. –

+6

Inoltre, dice: "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 sia 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. –

18

Un'altra opzione: 503 - Service Unavailable.

+3

[secondo W3C] (http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html) non è quello che vuoi dire al cliente (anche se significa "vieni 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, il che implica che si tratta di una condizione temporanea che verrà attenuata dopo un certo ritardo.Se noto, la lunghezza del ritardo può essere indicata in un Intestazione Retry-After. Se non viene restituito alcun Retry-After, il client DOVREBBE gestire la risposta come farebbe per una risposta 500. " – skalee

32

Il "problema", come è, è sul lato server: il client ha fatto una richiesta ben formata, ma il server non può soddisfarlo. Quindi sono incline a un "Errore del server", codice di stato 5xx. Disse the standard:

codici di stato di risposta che iniziano con la cifra "5" indicano i casi in cui il server è consapevole di aver commesso un errore o non è in grado di eseguire la richiesta ... il server dovrebbe includere un soggetto [che indica] se si tratta di una condizione temporanea o permanente.

Nota

  • "ha commesso un errore o è incapace di eseguire la richiesta": nonostante il loro titolo di "Server Error", che non sono solo per errori del server.
  • "temporanea o permanente": questi codici sono adatti per le risorse temporaneamente non disponibile, come la tua.

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

Il server è attualmente in grado di gestire la richiesta a causa di un sovraccarico temporaneo o di manutenzione del server. L'implicazione è che questa è una condizione temporanea che sarà alleviata dopo un certo ritardo. Se noto, la lunghezza del ritardo può essere indicata in un'intestazione Riprova dopo. Se non viene fornito alcun tentativo, il client DOVREBBE gestire la risposta come per una risposta 500.

Nota:

  • "una condizione temporanea che verrà risolta con un certo ritardo": vero per il vostro caso.
  • "sovraccarico temporaneo": non pedanticamente vero per il tuo caso. Ma, si potrebbe sostenere, erano il server molto più veloce, l'elaborazione in batch sarebbe già stato fatto quando il client ha effettuato la richiesta, quindi è una sorta di "sovraccarico": il cliente sta chiedendo le risorse più velocemente di quanto il server può renderli disponibili.
  • "il cliente deve gestire la risposta, come si farebbe per una risposta 500.": che è" Errore interno del server ", il tipo di risposta in caso di errore del server a causa di un bug. Lo standard sembra implicare che un client ben educato dovrebbe provare non in questo caso. così la vostra risposta dovrebbe includere un valore Retry-After. Si potrebbe fornire come valore il tempo di completamento stimato della successiva esecuzione del processo batch, o l'intervallo di esecuzione del processo batch.

Definizione del codice di stato proprio 5xx (591, ad esempio), anche se permitted, avrebbe la semantica sbagliata:

HTTP status co des sono estensibili ... Le domande devono comprendere la classe di qualsiasi codice di stato, come indicato dalla prima cifra, e trattare qualsiasi risposta non riconosciuta come equivalente al codice di stato x00 di quella classe

cliente avrebbe trattare il proprio codice di stato come 500, "Errore interno del server", che (come discusso sopra) non sarebbe corretto.

+1

Non riesco a vedere come è meglio di 202: http://benramsey.com/blog/2008/04/http-status-201-created-vs-202-accepted/ – JCCyC

+3

@ JCCyC il tuo blog è un buon caso per il ritorno un 202 in risposta a una richiesta di creare qualcosa (un POST o PUT). La domanda sembra essere chiedere cosa restituire per un GET. – Raedwald

+0

@ JCCyC potrebbe essere visto come una diversa sfumatura di non-ready-ness: immagina un ajax per quella risorsa, preferisci 202 come stato di successo o 503 come stato di errore? in modo da poter vedere quale significato preferisci implicitamente nel contesto della reazione della tua app alla risposta – rloth

14

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

A mio parere 302 (trovato) con l'intestazione Retry-After sarebbe l'opzione migliore, ma non sono sicuro che il campo Ubicazione dell'intestazione risposta possa essere uguale all'URL di richiesta. È un reindirizzamento circolare, comunque.

+2

Anche se è permessa, se il client non è implementato supporto per l'intestazione Retry-After, quindi un reindirizzamento 3xx alla stessa pagina potrebbe finire in 503 ... (facoltativamente con un'intestazione Retry-After, ovviamente) –

+0

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. –

11

io non voglio ritorno 404; questo è per cose che non esistono.

L'URL non corrisponde a una richiesta di qualcosa.

http://server/thingyapi/thingyblob/1234

il client richiede un thingyblob, che non esiste. Se esistesse, lo daresti a loro.

404.

+0

Sono contento che qualcuno abbia detto questo! Non posso credere che ci siano così tante persone che pensano che "503" sia una risposta appropriata. Per non parlare di alcuni altri strani suggerimenti. – Jason

+0

Anche se sono d'accordo sul fatto che un 404 è la risposta più appropriata qui, non risponde alla domanda dell'OP come indicare quando il thingy è disponibile :-). Penso che il campo Riprova dopo sembra il candidato migliore, ma può essere utilizzato solo ufficialmente per i codici 503 e 3xx. @ Jason: Penso che questo spieghi alcuni degli strani suggerimenti. –

+0

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

2

501 - non implementato

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

Questo è un collegamento a summary of 5xx errors.

+1

Per questa domanda sembra che la funzione stessa esista, ma l'elemento richiesto non lo fa. – Luke

+0

@Luke 501's descrizione dal link nella mia risposta, '... manca la capacità di soddisfare la richiesta. Di solito questo implica disponibilità futura '. Questo è esattamente ciò che l'OP chiedeva. Indipendentemente dal fatto che i dati siano o meno presenti sui suoi server o DB. Il risultato finale è che per ora non è accessibile tramite l'API. Pertanto l'API non può soddisfare la richiesta, ma vorrebbe implicare che sarà disponibile in futuro tramite il codice http. – Dan

-2

409 Conflitto

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

Potrebbe essere appropriato.

Se non è possibile soddisfare la richiesta restituendo i dati, non è un successo. Penso che 202 suggerisca che il server abbia accodato la richiesta e soddisferà la richiesta in seguito. Ma nel tuo caso, la richiesta è per i dati ora e ha fallito. Se riprovate più tardi è una richiesta diversa.

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

12

penso che 423 - Locked possono essere utilizzati per questo scopo:

L'(Locked) codice di stato 423 significa che la risorsa di origine o di destinazione di un metodo è bloccato. Questa risposta DOVREBBE contenere un codice precondizione o post-condizionale appropriato, come "lock-token-submitted" o "no-conflict-lock".

+1

Ottima risposta! Mi chiedo perché non ha più upvotes. – lex82

+4

Forse perché è un codice HTTP WebDAV? –

Problemi correlati