OTTIENI stato risorsa con corpo JSON o codice HTTP

4

Voglio fornire a mi di riposo il mio servizio iot per leggere lo stato di uno sprinkler on / off. Finora ho trovato due soluzioni:

  1. GET /api/sprinkler che restituisce 204 se su e 404 se off
  2. GET /api/sprinkler che restituisce 200 e {"status": "on"}

Il primo esempio è basato su questo . Restituendo il codice 404 implichiamo che la risorsa chiamata sprinkler non esiste. È anche l'assunzione corretta?

Non riesco a decidere quale sia il migliore. Preferisco i codici HTTP ma in questo caso diventa confuso. Quale dovrei usare?

    
posta gkiko 19.06.2016 - 13:19
fonte

3 risposte

2

Per il tuo caso, credo che la restituzione

{ "status" : "off" }

Con un codice di stato 200 è "corretto".

In pratica, non importa molto.

Quando Fielding pubblicò il suo famoso rant on hypertext , chiamò un particolare errore in questo modo:

Failure here implies that out-of-band information is driving interaction instead of hypertext.

Out-of-band in questo caso significa che l'informazione non può essere dedotta dal contenuto della risposta e dalla definizione del tipo di quel contenuto.

Nel tuo esempio, sembra che tu stia cercando di comunicare lo stato dell'irrigatore in modo fuori banda; "quando ottieni un 404, significa che lo sprinkler è spento" è - dal punto di vista di REST - un cheat.

Il modo in banda per inviare tali informazioni è inviando una rappresentazione dello stato dell'irrigatore. Ora, in realtà non c'è nulla che ti impedisca di inviare quella rappresentazione insieme a un 404 - RFC-7231 incoraggia i server a includere una spiegazione della condizione di errore, quindi questo va bene, ma la semantica è sbagliata: "Non sono riuscito a trovare la rappresentazione corrente della risorsa, e anche qui è la rappresentazione che Non ho trovato. "

L'esempio di API Gist è leggermente diverso da cosa hai proposto; dovresti assicurarti di esserne a conoscenza.

In primo luogo, si noti che l'URI di Gist identifica la stella , non la sostanza . In altre parole, considera questa stella come un'entità con un proprio ciclo di vita, piuttosto che come una semplice proprietà. GET / gists /: id / star restituisce la rappresentazione corrente della stella; quando la stella non esiste, non c'è una rappresentazione corrente da trovare e 404 NOT FOUND è appropriata.

Nel tuo esempio, lo sprinkler esiste sempre e ha una proprietà con valori on / off. Affermare che lo sprinkler non è stato trovato perché la proprietà ha il valore sbagliato non corrisponde realmente alla semantica.

Ciò che corrisponderebbe alla semantica sarebbe identificare come risorsa il flusso dell'acqua attraverso l'irrigatore. Una risposta 404 a GET / api / sprinkler / flusso ha perfettamente senso, semanticamente, quando lo sprinkler è spento e il flusso non esiste.

Si noti che questa è solo una questione di progettazione di URI / API - quanto bene l'ortografia di uri comunica ciò che sta accadendo ai lettori umani. Al computer non importa: sta solo seguendo un link. REST non si preoccupa, a patto che l'URI sia fornito dal server, piuttosto che assunto dal cliente. Mettendolo in un altro modo, l'ortografia dell'URI è analoga all'ortografia di un nome di variabile. Quindi se si volesse affermare che / api / sprinkler è l'identificatore per l'entità dell'acqua fluente, la semantica 200/404 andrebbe bene; potresti perdere punti nella revisione del codice per non essere conforme agli standard di denominazione.

Tuttavia, c'è il secondo punto, ovvero che l'API Gist è di fronte al libro dei record per gli elenchi e le stelle. Quando la descrizione della stella viene rimossa dal database gist, la stella è davvero sparita. D'altra parte, "sprinkler" suona come una cosa sul prato fuori nel mondo reale, che trasmette una sorta di segnale che stai riflettendo attraverso la tua API. In tal caso, 404 per indicare off non sembra affatto adatto - il segnale esiste, e lo stai ricevendo, ma ti sta solo dicendo che al momento non scorre acqua.

Le parole di Jim Webber su DDD e REST solleva quello che penso sia un punto importante

The web is not your domain, it's a document management system. All the HTTP verbs apply to the document management domain.

Lo farei ulteriormente e suggerisco che i codici di stato appartengono anche al dominio di gestione dei documenti. In altre parole, 404 dovrebbe significare "Non riesco a trovare il documento che hai richiesto", non "Ho trovato il documento che desideri, e ti sto dicendo che non posso farlo perché tu sappia cosa c'è dentro. "

Tutto ciò detto, 200/404 funzionerà, perché i vincoli con le informazioni fuori banda non si applicano alla tua situazione (la tua API non ha bisogno di ridimensionare le dimensioni del web, non ha bisogno per essere fattibile fino a quando il web, non stai cercando di definire una serie di tipi di media standardizzati per catturare tutte le informazioni in banda, ecc.)

    
risposta data 19.06.2016 - 18:03
fonte
3
GET /api/sprinkler that returns 200 and {"status": "on"/"off"/"damaged"/"no water".....}

A mio avviso, assegnare un significato ai codici di errore che hanno già un significato definito è una cattiva idea. Come distinguere tra sprinkler "off" e "client indicando l'url errato" eccezioni?

    
risposta data 19.06.2016 - 15:42
fonte
2

Da quanto ho capito, la soluzione 1 ha frainteso la semantica del codice di stato HTTP.

Da RFC HTTP / 1.1: Definizioni del codice di stato

10.4 Client Error 4xx

The 4xx class of status code is intended for cases in which the client seems to have erred.

Nel tuo esempio, è una questione di rappresentazione delle risorse. Perché probabilmente stai pensando che un irrigatore in% stato diOFF sia un errore e che uno sprinkler in% stato diON sia valido.

Tuttavia, il significato di una richiesta HTTP e una rappresentazione della risorsa sono cose completamente diverse.

Nel tuo caso il tuo cliente chiede: "qual è lo stato dello sprinkler"? Il server dovrebbe controllare la richiesta (intestazione e corpo). Se è valido, utilizzare il codice 2xx. Se un cliente ha fatto un errore, usa il codice 4xx. Se il server ha riscontrato un problema, utilizza il codice 5xx.

Quindi nel tuo esempio, la richiesta del cliente è perfettamente valida e dovrebbe essere riconosciuta con un codice di stato HTTP che lo indichi. Quindi vai avanti con 200 code:)

    
risposta data 19.06.2016 - 17:48
fonte

Leggi altre domande sui tag