Devo utilizzare i codici di stato HTTP per descrivere gli eventi a livello di applicazione

49

Diversi server con cui ho gestito restituiranno HTTP 200 per richieste che il client dovrebbe considerare un errore, con qualcosa come "successo: falso" nel corpo.

Questo non mi sembra una corretta implementazione dei codici HTTP, in particolare nei casi di autenticazione fallita. Ho letto i codici di errore HTTP riassunti sinteticamente in quanto, "4xx" indica che la richiesta non deve essere ripetuta fino a quando non viene modificata, mentre "5xx" indica che la richiesta può o non può essere valida e può essere tentata, ma non ha avuto successo. In questo caso 200: login fallito, o 200: impossibile trovare quel file, o 200: mancante parametro x, sicuramente sembra sbagliato.

D'altra parte, ho potuto vedere l'argomento che è stato fatto che '4xx' dovrebbe solo indicare un problema strutturale con la richiesta. Quindi è corretto restituire 200: utente / password errati anziché 401 non autorizzati perché il client è autorizzato a fare la richiesta, ma è errato. Questo argomento potrebbe essere riassunto come, se il server fosse in grado di elaborare la richiesta e fare una determinazione, il codice di risposta dovrebbe essere 200, e spetta al cliente controllare il corpo per ulteriori informazioni.

Fondamentalmente, questa sembra essere una questione di preferenza. Ma questo è insoddisfacente, quindi se qualcuno ha una ragione per cui uno di questi paradigmi è più corretto, mi piacerebbe sapere.

    
posta Kagan Mattson 16.12.2015 - 19:11
fonte

3 risposte

33

Domanda interessante.

Fondamentalmente, possiamo ridurlo nel modo giusto per classificare le cose in termini analoghi ai livelli OSI. HTTP è comunemente definito come un protocollo a livello di applicazione e HTTP è in effetti un protocollo client / server generico.

Tuttavia, in pratica, il server è quasi sempre un dispositivo di inoltro e il client è un browser Web, responsabile dell'interpretazione e del rendering del contenuto: il server trasferisce semplicemente le cose a un'applicazione arbitraria e le applicazioni restituiscono script arbitrari che il browser è responsabile dell'esecuzione. L'interazione HTTP stessa - i moduli richiesta / risposta, i codici di stato e così via - è principalmente un affare su come richiedere, servire e rendere il contenuto arbitrario nel modo più efficiente possibile, senza intralciare. Molti dei codici di stato e delle intestazioni sono infatti progettati per questi scopi.

Il problema con il tentativo di trascinare il protocollo HTTP per la gestione di flussi specifici dell'applicazione, è che ti rimane una delle due opzioni: 1) Devi rendere logica la tua richiesta / risposta un sottoinsieme delle regole HTTP; oppure 2) È necessario riutilizzare determinate regole e quindi la separazione delle preoccupazioni tende a diventare confusa. All'inizio questo può sembrare bello e pulito, ma penso che sia una di quelle decisioni di design che rimpiangerai quando il tuo progetto si evolverà.

Pertanto, direi che è meglio essere espliciti sulla separazione dei protocolli. Lascia che il server HTTP e il browser web facciano le loro cose, e lascia che l'app faccia la sua cosa. L'app deve essere in grado di fare richieste, e ha bisogno delle risposte - e la sua logica su come richiedere, come interpretare le risposte, può essere più (o meno) complessa della prospettiva HTTP.

L'altro vantaggio di questo approccio, che vale la pena menzionare, è che le applicazioni, in generale, non devono dipendere da un protocollo di trasporto sottostante (da un punto di vista logico). Lo stesso HTTP è cambiato in passato, e ora abbiamo HTTP 2 in entrata, dopo SPDY. Se visualizzi la tua app come nient'altro che un plug-in di funzionalità HTTP, potresti rimanere bloccato lì quando subentreranno nuove infrastrutture.

    
risposta data 17.12.2015 - 10:31
fonte
21

Questa domanda è basata su un po 'di opinione, ma in entrambi i casi.

Per come la vedo io, 200 può servire "errori soft". Quando si tratta di creare API, cerco di distinguere tra questi e "errori gravi".

"Errori software" verranno pubblicati con un codice di stato di 200, ma conterrà una descrizione di errore e uno stato di successo di false . Gli "errori soft" si verificano solo quando il risultato è "come previsto", ma non è un successo nel senso più stretto.

È importante notare che gli "errori software" sono più di un suggerimento per l'implementatore. Pertanto è importante fornire maggiori informazioni sull'errore, come un messaggio di errore leggibile dall'uomo e / o una sorta di codice che può essere utilizzato per fornire all'utente un feedback. Questi errori forniscono l'implementatore (e l'utente finale) con ulteriori informazioni su ciò che è accaduto sul lato server delle cose.

Ad esempio, supponiamo di avere un'API con una funzione di ricerca, ma durante una ricerca non vengono prodotti risultati. Questo non è errato, ma non è nemmeno un "successo", non nel senso più stretto della definizione.

Esempio formattato come JSON:

{
    "meta" {
        "success": false,
        "message": "Search yielded no results",
        "code": "NORESULTS"
    }
    "data": []
}

"Errori gravi" d'altra parte, verrà pubblicato con un codice di stato consigliato per l'errore. Utente non registrato? - 403 / 401. Input malformato? - 400. Errore del server? - 50X. E così via.

Ancora una volta, è un po 'basato sull'opinione pubblica. Alcune persone vogliono trattare tutti gli errori in modo uguale, "errore difficile" tutto. Nessun risultato trovato? Questo è un 404! Dall'altro lato della medaglia, nessun risultato di ricerca? - Questo è come previsto, nessun errore.

Un altro fattore importante da tenere in considerazione è la tua architettura, ad esempio; se interagisci con la tua API utilizzando le richieste XHR JavaScript e jQuery o AngularJS. Questi "errori duri" dovranno essere gestiti con un callback separato, mentre gli "errori soft" possono essere gestiti con il "successo" -callback. Senza rompere nulla, il risultato è ancora "come previsto". Il codice lato client può quindi esaminare lo stato e il codice di successo (o il messaggio). E stampalo all'utente finale.

    
risposta data 16.12.2015 - 20:18
fonte
13

Esistono due aspetti di un'API: lo sforzo di implementare l'API e lo sforzo di tutti i client di utilizzare correttamente l'API.

Come autore del client, so che quando invio una richiesta a un server web, posso ricevere un errore (mai parlato correttamente al server) o una risposta con un codice di stato. Devo gestire gli errori. Devo gestire una buona risposta. Devo gestire le risposte attese, documentate, "cattive". Devo occuparmi di qualsiasi altra cosa ritorni.

Progettando l'API, dovresti esaminare qual è il modo più semplice per il cliente di elaborare. Se il cliente invia una richiesta ben formata e puoi fare ciò che la richiesta ti chiede di fare, dovresti dare una risposta nell'intervallo 200 (ci sono alcuni casi in cui un numero diverso da 200 in tale intervallo è appropriato).

Se il cliente chiede "dammi tutti i record come ...", e ci sono zero, allora un 200 con successo e una serie di zero record è del tutto appropriato. I casi che menzioni:

"Accesso non riuscito" di solito dovrebbe essere un 401. "Impossibile trovare il file" dovrebbe essere un 404. "Il parametro mancante x" dovrebbe essere qualcosa intorno a 500 (in realtà, un 400 se il server capisce che la richiesta è cattiva e 500 se il server è totalmente confuso dalla mia richiesta e non ha idea di cosa sta succedendo). Restituire 200 in questi casi è inutile. Significa solo come autore di un cliente, non posso solo guardare il codice di stato, devo anche studiare la risposta. Non posso semplicemente dire "status 200, ottimo, ecco i dati".

Soprattutto il "parametro mancante" - non è qualcosa che avrei mai gestire . Significa che la mia richiesta non è corretta. Se la mia richiesta non è corretta, non ho un fallback per correggere quella richiesta errata - vorrei inviare una richiesta corretta per iniziare. Ora sono costretto a gestirlo. Ottengo un 200 e devo controllare se c'è una risposta "parametro mancante". È terribile.

Alla fine, ci sono una dozzina o due codici di stato per la gestione di molte situazioni diverse, e dovresti usarli.

    
risposta data 16.12.2015 - 22:45
fonte

Leggi altre domande sui tag