2012-02-21 3 views
58

Sto creando un'API RESTful che elabora un numero di interazioni utente, incluso l'inserimento di ordini tramite carte di credito memorizzate.Qual è la risposta del codice di stato HTTP appropriata per una richiesta generale non riuscita (non un errore)?

In caso di un ordine riuscito, restituisco un 200 OK e nel caso in cui la richiesta di ordine non sia corretta o non valida restituisco una richiesta non valida di 400. Ma cosa dovrei restituire se c'è un problema durante l'elaborazione effettiva dell'ordine?

  1. Client POSTS ordine al server per una risorsa utente. Se l'utente non esiste, viene restituito 404 non trovato.
  2. Il formato e le informazioni dell'ordine sono convalidati. Se non è valido, viene restituita 400 Richiesta non valida.
  3. L'ordine viene elaborato. Se l'ordine ha esito positivo, viene restituito un 201 creato per l'ordine. Se si verifica un errore imprevisto, viene restituito un errore di 500 server.

L'ultimo passaggio è il problema: cosa restituisco se l'ordine non viene completato per altri motivi? possibili scenari potrebbero includere:

  • prodotto è esaurito
  • utente limite massimo ordine raggiunto
  • fallimento
  • credito transazione con carta (fondi insufficienti, ecc)

Questo non sembra come sarebbe appropriato per un 400 o un 500. Se potessi vederlo come un 400 se non c'è un codice migliore, la richiesta non era valida secondo le regole aziendali. Semplicemente non sembra accurato.

Modifica: trovato anche this existing discussion dello stesso argomento. Tutte le risposte sembrano puntare a utilizzare i codici di stato per questo tipo di violazione, con alcune discussioni tra l'utilizzo di 400, 409 o l'estensione 422.

+3

Mi piace '422 entità Unprocessable' per errori di convalida. E lo userebbero per i tuoi esempi sopra, includere un messaggio nella risposta con il problema aziendale attuale "Il prodotto è esaurito" e possibilmente aggiungere i tuoi "codici" se il cliente ha bisogno di prendere decisioni diverse in base alla risposta – house9

risposta

54

È necessario utilizzare 400 per le regole aziendali. Non restituire 2xx se l'ordine non è stato accettato. HTTP è un protocollo applicativo, non dimenticarlo mai. Se restituisci 2xx il cliente può assumere che l'ordine è stato accettato, indipendentemente dalle informazioni che hai inviato nel corpo.


Da RESTful Web Services Cookbook:

Un errore comune che alcuni servizi web fanno è quello di restituire un codice di stato che riflette il successo (codici di stato da 200 a 206 e da 300 a 307) ma includono un corpo del messaggio che descrive una condizione di errore. Questa operazione impedisce al software che riconosce HTTP di rilevare errori. Nell'esempio , una cache la memorizzerà come risposta positiva e la servirà ai client successivi anche quando i client potrebbero essere in grado di effettuare una richiesta corretta.

Lascio a voi decidere tra 4xx e 5xx, ma è necessario utilizzare un codice di stato di errore.

+1

hai qualche esempio o riferimento per questo approccio rispetto all'altro? Le risposte sia di Your che di Widor hanno senso, una dal punto di vista di HTTP come protocollo di applicazione, e l'altra come strettamente legata allo scopo del trasferimento. La specifica lo definisce come un "protocollo a livello di applicazione", che è un po 'vago. Ho anche visto sia le prospettive che gli esempi in giro per il Web durante la ricerca di questo. – Raelshark

+0

questo è vero. –

15

È necessario utilizzare 4xx per un errore del client se il client può modificare la richiesta per aggirare l'errore. Usa un 5xx per un errore del server che il client non può davvero aggirare.

Prodotto esaurito sarebbe un errore del server. Il client non può modificare la richiesta in alcun modo per aggirare l'errore.Potresti passare a un altro prodotto ma non sarebbe una nuova richiesta?

Il limite massimo di ordini dell'utente raggiunto è anche un errore del server. Nulla che il client possa fare per aggirare quell'errore.

Errore di transazione con carta di credito sarebbe un errore del client. Il client potrebbe inviare nuovamente la richiesta con un metodo di pagamento diverso o un numero di carta di credito per aggirare l'errore.

+3

Se viene raggiunto il limite dell'ordine, il client non dovrebbe avvisare l'utente e lasciare che cambi la richiesta in modo appropriato? Sembra un errore 4xx. Lo stesso vale per il prodotto esaurito. Gli errori 5xx sono intesi per errori causati dal malfunzionamento del sistema in qualche modo, non per un'azione non consentita da una regola aziendale. –

+3

Sono d'accordo con il commento sopra. Gli errori 5xx sono per quando il server ha problemi. Errori 4xx per le regole aziendali. – Merc

2

Non credo che 400 possa essere utilizzato per tutti gli scenari di business. Può essere utilizzato per la convalida dei dati di base. Oltre a questo, potremmo avere difficoltà nel tempo ad integrare altre logiche di business in questo codice di errore. L'errore gestito da questo sono principalmente gli errori di progettazione che lo sviluppatore incontrerà probabilmente durante la codifica del client.

Supponiamo che tutti i parametri siano corretti e diciamo che stiamo passando il numero di account utente nella richiesta.

Quindi la richiesta non è più una richiesta errata, il server è in grado di accettare la richiesta. Ma ora si rifiuta di completare la richiesta sulla base di nuove informazioni disponibili che è - l'account non ha un equilibrio sufficiente.

Suggerirei di utilizzare 403 con il messaggio di errore appropriato in questi scenari.

Altro possibile codice di errore potrebbe essere 409 conflitto. Ma questo è usato in scenari in cui la risorsa è in uno stato coerente.

5

So che questa domanda è vecchia, ma oggi mi è venuta la stessa domanda. Se il mio utente ha esaurito i crediti, quale codice di stato deve restituire la mia API REST?

tendo a propendere per 402 Payment Required:

Secondo Wikipedia:

Riservato per uso futuro. L'intenzione originale era che questo codice potesse essere usato come parte di una qualche forma di denaro digitale o schema di micropagamenti, ma ciò non è accaduto e questo codice non viene solitamente usato. L'API di Google Developers utilizza questo stato se un determinato sviluppatore ha superato il limite giornaliero per le richieste. è stato raggiunto

PAYMENT_REQUIRED (402)

  • Un limite di budget giornaliero impostato dallo sviluppatore:

E infatti they do.

  • L'operazione richiesta richiede più risorse di quelle consentite dalla quota. Il pagamento è richiesto per completare l'operazione.
  • L'operazione richiesta richiede un tipo di pagamento dall'utente autenticato.
  • 10

    tipo di errore: codice

    4×× Client Error 
    

    Errore:

    422 Unprocessable Entity 
    

    Il server capisce il tipo di contenuto dell'entità richiesta (quindi un codice di stato Tipo 415 di supporto non è inappropriato) e la sintassi dell'entità richiesta è corretta (quindi un codice di stato 400 Richiesta non valida) non è stato in grado di elaborare le istruzioni contenute.

    Ad esempio, questa condizione di errore può verificarsi se un corpo di richiesta XML contiene istruzioni XML ben formate (vale a dire, sintatticamente corrette), ma semanticamente errate.

    https://httpstatuses.com/422

    2

    vado con 406 Not Acceptable.

    Ecco un elenco 4xx:

    const HTTP_BAD_REQUEST = 400; 
    const HTTP_UNAUTHORIZED = 401; 
    const HTTP_PAYMENT_REQUIRED = 402; 
    const HTTP_FORBIDDEN = 403; 
    const HTTP_NOT_FOUND = 404; 
    const HTTP_METHOD_NOT_ALLOWED = 405; 
    const HTTP_NOT_ACCEPTABLE = 406; 
    const HTTP_PROXY_AUTHENTICATION_REQUIRED = 407; 
    const HTTP_REQUEST_TIMEOUT = 408; 
    const HTTP_CONFLICT = 409; 
    const HTTP_GONE = 410; 
    const HTTP_LENGTH_REQUIRED = 411; 
    const HTTP_PRECONDITION_FAILED = 412; 
    const HTTP_REQUEST_ENTITY_TOO_LARGE = 413; 
    const HTTP_REQUEST_URI_TOO_LONG = 414; 
    const HTTP_UNSUPPORTED_MEDIA_TYPE = 415; 
    const HTTP_REQUESTED_RANGE_NOT_SATISFIABLE = 416; 
    const HTTP_EXPECTATION_FAILED = 417; 
    const HTTP_I_AM_A_TEAPOT = 418;            // RFC2324 
    const HTTP_MISDIRECTED_REQUEST = 421;           // RFC7540 
    const HTTP_UNPROCESSABLE_ENTITY = 422;          // RFC4918 
    const HTTP_LOCKED = 423;              // RFC4918 
    const HTTP_FAILED_DEPENDENCY = 424;           // RFC4918 
    const HTTP_RESERVED_FOR_WEBDAV_ADVANCED_COLLECTIONS_EXPIRED_PROPOSAL = 425; // RFC2817 
    const HTTP_UPGRADE_REQUIRED = 426;           // RFC2817 
    const HTTP_PRECONDITION_REQUIRED = 428;          // RFC6585 
    const HTTP_TOO_MANY_REQUESTS = 429;           // RFC6585 
    
    +3

    Mentre il nome del codice di stato 406 può sembrare accurato da solo, è necessario essere consapevoli che ogni codice di stato ha una descrizione testuale autorevole. La descrizione del codice di stato 406 * non è adatta * per il caso in esame. Vedere https://httpstatuses.com/406, ad esempio. – Zero3

    +0

    @ Zero3 è corretto, questo codice indica che il tipo di risposta non è accettabile, in quanto vi è una mancata corrispondenza tra le intestazioni Accept inviate dal client e i MediaType inviati dall'endpoint, ad es. applicazione/json vs. testo/semplice – Gregor