I codici di stato HTTP devono essere utilizzati per rappresentare errori di business logic su un server?


20

Sono un po 'all'incrocio con qualche progetto API per un client (JS in un browser) per parlare con un server. Utilizziamo HTTP 409 Conflict per rappresentare il fallimento di un'azione a causa di un blocco di sicurezza attivo. Il blocco satefy impedisce agli sviluppatori di apportare accidentalmente modifiche ai sistemi di produzione dei nostri clienti. Mi è stato assegnato il compito di gestire i 409 un po 'più con garbo sul client per indicare perché una determinata chiamata API non è riuscita.

La mia soluzione era quella di avvolgere i gestori di errori di una qualsiasi delle nostre chiamate AJAX che mostreranno una notifica sul client quando qualcosa fallisce a causa di 409 - tutto va bene e funziona bene insieme ad altri errori 4XX e 5XX che usano lo stesso meccanismo.

Si è verificato un problema in cui uno dei nostri gestori di route risponde con 409s quando riscontra un errore di logica aziendale: il mio wrapper AJAX segnala che il blocco di sicurezza è attivo, mentre il gestore degli errori esistente del client segnala quale (pensa) il problema si basa sul corpo della risposta. Una soluzione semplice sarebbe quella di modificare la risposta del gestore o il codice di stato che utilizziamo per rappresentare il blocco di sicurezza.

Il che mi porta al mio incrocio: i codici di stato HTTP dovrebbero anche essere usati per rappresentare errori di logica aziendale? Questa domanda affronta lo stesso problema che sto affrontando, ma non ha ottenuto molta trazione. Come suggerito nella risposta collegata, mi sto orientando verso l'utilizzo di HTTP 200 OK con un corpo appropriato per rappresentare il fallimento all'interno della logica aziendale.

Qualcuno ha delle opinioni forti qui? Qualcuno è in grado di convincermi che questo è il modo sbagliato di rappresentare il fallimento?


3
Esito a pubblicare la mia semplice opinione come risposta. In breve: in genere evito di utilizzare i codici di stato HTTP per rappresentare errori aziendali. Dovrebbero riguardare solo lo stato della comunicazione tra client e server. Un codice di stato adatto per la restituzione della convalida o degli errori di logica aziendale sarebbe 400 Bad Request. Il motivo di questa separazione è perché i sistemi, gli sviluppatori o i lettori di documenti futuri potrebbero essere confusi dalla tua deviazione dello standard mondiale.
Ivo Coumans,

@IvoCoumans: per favore, fai di questo ^ una risposta per poterlo votare. 400 Bad Requestcome un codice HTTP generale sembra meglio coprire gli errori di business logic come classe.
9000,

Preferenze personali, ma tendo a utilizzarle 400 Bad Requestquando mancano o non possono essere letti / analizzati i dati. Cioè i dati della richiesta stessa sono in qualche modo cattivi.
Kasey Speakman

Espandere il significato di "errore di logica aziendale". È estremamente vago. Intendi un input non valido secondo i (corretti) controlli di convalida dei dati, input che potrebbero essere validi in qualche altro momento ma che non sono validi nello stato corrente o un bug nella logica aziendale in cui rifiuta un input valido?
jpmc26,

@ jpmc26 Ero intenzionalmente vago perché era una domanda generale. I server hanno gestito bene la richiesta ma hanno deciso che la query / asserzione non aveva senso.
Joe Shanahan,

Risposte:


19

Kasey copre il punto principale.

L'idea chiave in qualsiasi API web: stai adattando il tuo dominio per sembrare un archivio documenti. GET / PUT / POST / DELETE e così via sono tutti modi per interagire con l'archivio documenti.

Quindi un modo di pensare a quali codici usare, è capire quale sia l'operazione analoga in un archivio documenti e come sarebbe questo fallimento in quell'analogo.

2xx è completamente inadatto

La classe 2xx (riuscita) del codice di stato indica che la richiesta del client è stata ricevuta, compresa e accettata correttamente.

Anche 5xx non è adatto

La classe 5xx (errore del server) del codice di stato indica che il server è consapevole di aver commesso un errore

In questo caso, il server non ha commesso un errore; è consapevole che al momento non è necessario modificare tale risorsa in questo modo.

Gli errori di logica aziendale (ovvero che l'invariante aziendale non consente la modifica proposta in questo momento) sono probabilmente 409

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 inviare nuovamente la richiesta. Il server DOVREBBE generare un payload che includa informazioni sufficienti per consentire a un utente di riconoscere l'origine del conflitto.

Nota quest'ultimo bit: il payload della risposta 409 dovrebbe comunicare informazioni al consumatore su ciò che è andato storto e includere idealmente controlli ipermediali che conducono il consumatore alle risorse che possono aiutare a risolvere il conflitto.

La mia soluzione era quella di avvolgere i gestori di errori di una qualsiasi delle nostre chiamate AJAX che mostreranno una notifica sul client quando qualcosa fallisce a causa di 409 - tutto va bene e funziona bene insieme ad altri errori 4XX e 5XX che usano lo stesso meccanismo.

E vorrei indicare questo come problema; l'implementazione presso il client presupponeva che il codice di stato fosse sufficiente per definire il problema. Invece, il codice del client dovrebbe rivedere il payload e agire in base alle informazioni disponibili lì.

Dopo tutto, è così che farebbe un archivio documenti

409  Conflict

your proposed change has been declined because ${REASON}.  
The following resolution protocols are available: ${LINKS[@]})

Lo stesso approccio con a 400 Bad Requestsarebbe anche accettabile; che approssimativamente "si traduce in" Si è verificato un problema con la tua richiesta. Non possiamo preoccuparci di capire quale codice di stato sia la soluzione migliore, quindi eccoti qui. Vedi il payload per i dettagli. "

Vorrei utilizzare 422. L'input è valido, quindi 400 non è il codice di errore corretto da utilizzare

La specifica WebDAV include questa raccomandazione

Il codice di stato 422 (entità non elaborabile) indica che il server comprende il tipo di contenuto dell'entità richiesta (quindi un codice di stato 415 (tipo di supporto non supportato) è inappropriato) e la sintassi dell'entità richiesta è corretta (quindi un 400 (richiesta non valida) ) il codice di stato non è appropriato) ma 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 (cioè sintatticamente corrette), ma semanticamente errate.

Non credo che sia abbastanza una partita (anche se sono d'accordo che solleva qualche dubbio su 400come alternativa). La mia interpretazione è che 422significa "hai inviato l'entità sbagliata" dove si 409trova "hai inviato l'entità nel momento sbagliato".

In altre parole, 422indica un problema con il messaggio di richiesta considerato separatamente, dove 409indica che il messaggio di richiesta è in conflitto con lo stato corrente della risorsa.

La discussione di Ben Nadal su 422 può essere utile da considerare.


5
" stai adattando il tuo dominio in modo che assomigli ad un archivio di documenti " - Mi piacerebbe vedere le persone leggere questo e comprendere appieno tutte le conseqenze e le implicazioni prima che decidano per (o contro) REST. Veramente.
JensG,

"Errori di logica aziendale" suona come "input non valido", che di solito è un diritto 400, poiché non esiste un codice di errore più specifico per esso. Se l'input non è valido, il server ha un bug e 500 è appropriato. La tua risposta sembra assumere troppo sulla natura di un "errore di logica aziendale".
jpmc26,

Vorrei utilizzare 422. L'input è valido, quindi 400 non è il codice di errore corretto da utilizzare
Konrad

19

Nella mia esperienza, i codici di errore HTTP sono insufficienti per rappresentare errori aziendali. Tuttavia, sono utili per rappresentare le classi di errori.

Pertanto, la mia raccomandazione sarebbe quella di utilizzare i codici di errore HTTP per le categorie di errori, ma scegliere un errore specifico per i guasti della logica aziendale (ad esempio 409 Conflitto ... 200 OK sarebbe fuorviante qui) e includere i dati nella risposta indicando l'errore aziendale specifico . Assicurati che faccia parte del contenuto della risposta e non del testo di stato perché alcuni browser ignorano il testo di stato personalizzato. La lingua che mi piace usare ha i tipi di unione che sono convenienti per rappresentare i messaggi. Ma potresti anche definire costanti di stringa per casi di errore.

Esempi

// error with text response
409 Conflict "safety_lock_engaged"
409 Conflict "customer_not_eligible_for_selected_discount"
// warning with JSON response
202 Accepted { "backorderedProductIds": [ 37, 476 ] }

I codici di stato 4xx sopra 400 hanno significati molto specifici. Scegli 400 se il tuo caso non è specificamente coperto dagli altri.
jpmc26,

@ jpmc26 Se non utilizzo i codici di stato in questo modo, non vengono mai utilizzati. Ma sentiti libero di usarli nel modo giusto e corretto nelle tue risposte.
Kasey Speakman,

In un certo senso, hai ragione. Non vengono mai usati. I significati scelti per i codici specifici non sembrano essere casi d'uso molto comuni per la maggior parte delle applicazioni. Va bene. Ci sono anche molte eccezioni che non scriviamo mai codice da catturare.
jpmc26,

@ jpmc26 Beh, le eccezioni non sono il modello migliore da seguire . Ma certo, vai avanti.
Kasey Speakman,

Non lanciare o catturare specifici tipi di eccezione è l'analogo del non usare mai codici HTTP specifici o altri codici di errore. Ho pensato che questo sarebbe ovvio. Se un modello di eccezione sia "il migliore" è assolutamente irrilevante al punto.
jpmc26,

5

In generale, eviterei di utilizzare i codici di stato HTTP per rappresentare specifici errori di logica aziendale. Questo perché hanno già un significato semantico definito dallo standard mondiale. Altri sistemi, nuovi sviluppatori e così via saranno confusi dalla tua deviazione dallo standard.

Ciò che ho scoperto in ricerche recenti, simili, è che è generalmente accettato l'uso 400 Bad Requestin caso di errori di convalida e simili. In questo modo, si utilizza un codice di stato per tutti gli errori di logica aziendale.

Per inciso, 409dovrebbe essere usato quando una risorsa è cambiata durante la modifica e ha provato a salvarla di nuovo.


4

È possibile utilizzare "Richiesta non valida" e includere l'ID della regola aziendale violata oltre a ulteriori dettagli sul corpo della risposta.


Non so whey, questo è stato votato in negativo. Ecco come possono le aziende restituire eccezioni commerciali.
Skadoosh,
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.