Ich arbeite mit einer REST-API, die sich auf einem Server befindet, der Daten für eine Vielzahl von IoT-Geräten verarbeitet.
Meine Aufgabe ist es, den Server mithilfe der API abzufragen, um bestimmte Leistungsinformationen zu diesen Geräten zu erfassen.
In einem Fall erhalte ich eine Liste der verfügbaren Geräte und ihrer entsprechenden IDs und frage später den Server nach weiteren Details unter Verwendung dieser IDs (GUIDs) ab.
Der Server gibt 500 Internal Server Error
eine Abfrage für eine dieser IDs zurück. In meiner Anwendung wird eine Ausnahme ausgelöst und es werden keine Details zu dem Fehler angezeigt. Wenn ich die Antwort genauer mit Postman untersuche , kann ich feststellen, dass der Server JSON in dem Body zurückgegeben hat, der Folgendes enthält:
errorMessage: "This ID does not exist"
.
Ignorieren Sie zunächst die Tatsache, dass der Server die ID angegeben hat - dies ist ein separates Problem für den Entwickler.
Sollte eine REST-API ein zurückgeben, um 500 Internal Server Error
zu melden, dass eine Abfrage auf ein nicht vorhandenes Objekt verweist? Meines Erachtens sollten sich die HTTP-Antwortcodes ausschließlich auf den Status des REST-Aufrufs und nicht auf die internen Mechanismen der API beziehen. Ich würde eine 200 OK
Antwort mit dem Fehler und der Beschreibung erwarten , die Eigentum der betreffenden API wäre.
Ich habe den Eindruck, dass es je nach Struktur des REST-Aufrufs einen potenziellen Unterschied in der Erwartung gibt.
Betrachten Sie diese Beispiele:
http://example.com/restapi/deviceinfo?id=123
http://example.com/restapi/device/123/info
Im ersten Fall wird die Geräte-ID als GET-Variable übergeben. Ein 404 oder 500 würde anzeigen, dass der Pfad ( /restapi/deviceinfo
) entweder nicht gefunden wurde oder zu einem Serverfehler führte.
Im zweiten Fall ist die Geräte-ID Teil der URL. Ich würde ein besseres Verständnis haben 404 Not Found
, könnte aber trotzdem darüber streiten, welche Teile des Pfades als Variablen gegenüber Endpunkten interpretiert werden.
quelle
Antworten:
Ich denke, eine 404-Antwort ist hier die beste semantische Übereinstimmung, da die Ressource, die Sie gesucht haben (dargestellt durch den für die Abfrage verwendeten URI), nicht gefunden wurde. Die Rückgabe einer Fehlernutzlast im Body ist sinnvoll, aber nicht erforderlich.
Gemäß RFC 2616 lautet die Definition des 404-Statuscodes:
quelle
/questions
derselbe/questions/368213
. Dieser Endpunkt ist in Ihrem Szenario nicht vorhanden. Stellen Sie sich das so vor: Wenn Sie ein GET für / foo / bar durchführen und es keinen Balken gibt, warum sollte die Antwort anders sein, wenn / foo existiert oder nicht?How do you differentiate between a 404 meaning "the query returned no results" and a 404 meaning "the endpoint does not exist"?
- 400 ungültige Anforderung.Ich werde Ihre Beispiele verwenden.
Wenn der Endpunkt ein json- Array zurückgibt , ist die beste Wahl für
200 OK
ein leeres Array, wenn kein Ergebnis gefunden wurde.Wenn der Endpunkt ausgelegt ist , eine Rückkehr einzelnes Ergebnis , wäre meine Wahl
404 NOT FOUND
, weil für mich die richtige Syntax für diese Art von Endpunkt ist:http://example.com/restapi/deviceinfo/123
. Normalerweise verwende ich den Anforderungsparameter nur zum Filtern und wenn mein Endpunkt ein Array zurückgibt.Ich denke , diese Frage wurde bereits beantwortet hier . POST oder GET, die bessere Wahl scheint,
404 NOT FOUND
weil die Ressource123
nicht gefunden wurde.In beiden Fällen sehe ich nicht die Notwendigkeit, den Grund für die Anfrage zu erklären, wurde nicht abgeschlossen. Die Anforderungsinformationen und der HTTP-Code erklären bereits, warum.
quelle
/itms/1234
oder durcheinander gebracht haben/items/12234
.HTTP 404
ist korrekt, da der Server versteht, nach welcher Ressource der Client fragt, diese Ressource jedoch nicht hat.Die Tatsache, dass Sie mit einer "REST-API" arbeiten, ist der Schlüssel. Die API sollte sich so verhalten, als würde sie eine REpresentational State Transfer durchführen und keine Funktion ausführen. (Sicher, der Begriff "REST" hat eine breitere Bedeutung erhalten, aber Sie können seine wörtliche Bedeutung auch hier sinnvoll verwenden.) Der Client hat nach dem Status einer durch die URL beschriebenen Ressource gefragt
http://example.com/restapi/device/123/info
. Ein Querystring (/deviceinfo?id=123
) würde die Situation nicht ändern. Der Server weiß, dass Sie den Status von Gerät 123 übertragen möchten, erkennt dies jedoch nicht als bekannte Ressource. DaherHTTP 404
.Die anderen möglichen Antworten, die hier diskutiert werden, haben ebenfalls spezifische Bedeutungen:
HTTP 200
- Wir haben den Staat für Sie; Es ist im Antworttext.HTTP 204
- Wir haben den Staat für Sie; es ist leer.HTTP 400
- Wir können nicht sagen, nach welcher Ressource Sie fragen. Korrigieren Sie Ihre URL.HTTP 500
- Wir haben versagt. Nicht deine Schuld.Siehe RFC 2616 Sec. 10 entsprechend.
quelle
Ein 5xx-Fehler wird normalerweise verwendet, um anzuzeigen, dass der Server einen Fehler festgestellt hat und die Anforderung nicht ausführen kann. Wenn der Server die Anforderung entgegennimmt, sie erfolgreich analysieren kann und dann seine Arbeit tut, sollte dies keinen 5xx-Fehler zurückgeben.
Ich bin mir nicht sicher, ob es irgendeine Konvention gibt, was zurückgegeben werden soll, wenn eine Abfrage keine Ergebnisse liefert. Ich habe sowohl das gesehen, was Sie beschreiben (200 mit einem Körper, der eine Nachricht enthält), als auch einen 404, der angibt, dass keine Ergebnisse gefunden wurden. Die 200 ist wahrscheinlich am sinnvollsten - die Anforderung wurde erfolgreich ausgeführt, und es gab keine Probleme mit der Anforderung des Clients oder während der Verarbeitung der Anforderung durch den Server. Ein Body kann eine Nachricht an den Client übermitteln.
Ich würde beide Beispiele (
http://example.com/restapi/deviceinfo?id=123
undhttp://example.com/restapi/device/123/info
) gleich behandeln - das123
ist ein Parameter. In beiden Fällen gibt es verschiedene Möglichkeiten, eine Anforderung zum Abrufen von Geräteinformationen für ein Gerät mit der ID 123 zu strukturieren.Zunächst würde ich Autorisierung und Authentifizierung in Betracht ziehen. Wenn der Benutzer nicht über die entsprechenden Berechtigungen verfügt, würde ich eine 403 oder eine 401 entsprechend zurückgeben. Obwohl es als "nicht autorisiert" bezeichnet wird, handelt es sich nach meinem Verständnis bei 401 mehr um Authentifizierung und bei 403 um nicht autorisiert oder um die Verweigerung von Berechtigungen. Ich wäre hier jedoch nicht zu wählerisch, wenn Sie sich nur für alle Authentifizierungs- und Autorisierungsfehler an 403 halten möchten.
Dann würde ich die ID behandeln. Basierend auf Ihrem Beispiel sieht es so aus, als wäre es eine numerische ID. Wenn ein nicht numerischer Wert angegeben würde, würde ich eine 400 zurückgeben. Wenn der Parameter möglicherweise eine gültige Gerätekennung sein könnte, würde ich mit der Verarbeitung fortfahren. Wenn es andere Argumente gäbe, würden sie auch hier überprüft. Ich würde erwarten, dass der Antworttext angemessene Informationen darüber enthält, warum die Anfrage schlecht war.
Wenn alle Parameter gültig wären, würde ich mit der Verarbeitung der Anfrage beginnen. Wenn das System oder eine Abhängigkeit (eine Datenbank, ein Drittanbieter-Service, ein anderer interner Service) nicht verfügbar ist, würde ich einen 5xx-Code zurückgeben - 503 wäre spezifisch, aber 500 wäre auch akzeptabel. In jedem Fall würde ich eine Leiche mit zusätzlichen Details zurückgeben. Beachten Sie, dass, wenn eine externe Abhängigkeit ein 408-Anforderungs-Timeout meldet, ich das esse und eine 500 an meinen Client zurückgebe, sodass ein Client nur dann eine 408 erhalten kann, wenn die Anforderung an mein System abgelaufen ist. Wenn das System in der Lage ist, die Anfrage zu vervollständigen, würde ich eine 200 und die entsprechende Stelle zurückgeben.
204 kann in einigen Fällen hilfreich sein, hindert Sie jedoch daran, einen Antworttext zu senden. Insbesondere in einer API-Einstellung erscheint es in den meisten Fällen als die richtige Entscheidung, einen Antworttext mit Informationen zu senden, die in einen Protokollierungs- oder Berichtsmechanismus eingegeben werden können.
Das einzige Mal, dass ein 404 zurückgegeben wird, ist, wenn der Server keinen
/deviceinfo
Endpunkt oder keinen/device/:id/info
Endpunkt hat.Ich würde eine ID, die nicht gefunden wird, nicht als dieselbe wie die nicht gefundene Ressource betrachten. Die Ressource ist die Geräteinformation für ein bestimmtes Gerät (in Ihrem Beispiel). Die Rückgabe eines 404 würde bedeuten, dass die Ressource (die Geräteinformationen) nicht vorhanden ist. Ein 200 mit einem geeigneten Körper bedeutet, dass das System tatsächlich Geräteinformationen bereitstellen kann. Möglicherweise ist ein Gerät mit der angegebenen ID vorhanden oder nicht.
quelle
device: 123; status: not found;
. Dann weiß ich, dass die Abfrage funktioniert hat und dass die API mir nützliche Informationen liefert.Ein HTTP-Fehler der 500er-Serie weist auf eine Fehlfunktion des Servers hin. Abgesehen von
501 Not Implemented
und505 HTTP Version Not Supported
hat die Verwendung dieser Fehlercodes die Implikation, dass ein erneuter Versuch der Anforderung zu einem späteren Zeitpunkt erfolgreich sein kann (obwohl dies nur503 Service Unavailable
explizit angegeben wird). Im Idealfall sollte ein Server niemals einen dieser Codes produzieren, obwohl die Unfähigkeit, fehlerfreie Software zu schreiben und den Server mit unendlichen Ressourcen auszustatten, bedeutet, dass Sie diese von Zeit zu Zeit benötigen.Für ein "Objekt existiert nicht" -Ergebnis sollten Sie wahrscheinlich entweder
404 Not Found
(wenn die Anforderung ein Objekt nach Namen enthält) oder200 Success
einen leeren Ergebnistext (wenn Sie ein Objekt nach Attributen suchen) zurückgeben.204 No Content
sieht verlockend aus, aber ich würde es nur in Situationen verwenden, in denen das Fehlen eines Antwortkörpers das erwartete Ergebnis ist.quelle
Wenn ich als Client Ihrer API einen der folgenden Aufrufe vornehme:
http://example.com/restapi/deviceinfo?id=123
http://example.com/restapi/device/123/info
Ich erwarte, dass ich ein (Repräsentations-)
DeviceInfo
Objekt zurückerhalte (oder auf jeden Fall einen bestimmten Typ, egal ob es sich um einen formalen Typ handelt oder nur um etwas, das einer dokumentierten "Ententyp" -Konvention entspricht). Ich möchte, dass ein200
Status bedeutet, dass ich tatsächlich einen habe, und ich kann fortfahren und ihn verwenden.Für REST-APIs stelle ich mir 400 und 500 Statuscodes als Ausnahmen vor. Sie geben damit an, wann Sie keine "normale" Antwort auf die von Ihnen empfangene Anfrage zurückgeben können. Der Client muss also etwas Außergewöhnliches tun, anstatt die erwarteten Informationen zu verarbeiten.
Dies bedeutet, dass ich als API-Konsument eine Art Checked-Rest-Call-Funktion verwenden kann, die eine Antwort abruft oder eine Ausnahme auslöst. Das ist großartig; Meine normale Logik kann linearer Code sein, und ich kann meine Fehlerbehandlung so organisieren, wie ich es im lokalen Code tue. Unerwartete 404-Werte werden als "Keine Ressource gefunden" -Ausnahmen angezeigt, ohne dass ich etwas tun muss, und nicht als "Fehlende Attribute" -Fehler, wenn ich später verarbeite,
{ errorMessage: "Device 123 not found" }
als wäre es einDeviceInfo
Objekt.Wenn Sie Grund , dass der Endpunkt
http://example.com/restapi/deviceinfo
wird gefunden, und es ist nur die ,id=123
die nicht, und so zurückkehren 200 mit einer Fehlermeldung im Körper, dann bist du zu schaffen genau die gleiche Art von Schnittstellenproblemen als C - Funktionen , die entweder einer Rückkehr könnten Richtiges Ergebnis oder ein Fehlercode oder Methoden, die Probleme durch willkürliche Rückgabe anzeigennull
. Als Benutzer Ihrer Benutzeroberfläche ist es viel angenehmer, Fehler durch einen "separaten" Kanal von regulären Rücksendungen anzeigen zu lassen. Dies gilt auch hier, obwohl HTTP-200-, HTTP-404- und HTTP-500-Antworten aus der Sicht einer niedrigen Ebene der gleiche Kanal sind. Sie sind standardisiert und leicht zu unterscheiden, sodass mein REST-Client-Framework diese Status problemlos aktivieren kann, um sie in die richtigen Strukturen in meiner Sprache umzuwandeln. Um dasselbe mit der JSON-Ebene zu tun (wo Sie immer 200 sagen und mir entweder eineDeviceInfo
oder eine Fehlermeldung geben), muss ich einige Kenntnisse über die von Ihnen verwendeten JSON-Schemas einbetten.Verwenden Sie daher nur 200, wenn Sie einen gültigen Wert des erwarteten Typs zurückgeben können (daher
http://example.com/restapi/search-devices?colour=blue
kann 200 mit einem leeren Array zurückgegeben werden, wenn keine blauen Geräte vorhanden sind; ein leeres Array ist ein gültiges Array und eine sinnvolle Antwort auf die Anforderung "I möchte die details aller blauen geräte "). Wenn dies nicht möglich ist, verwenden Sie den am besten geeigneten Nicht-200-Statuscode. Auch wenn "Gerät 123 nicht vorhanden" die richtige Antwort auf "Geben Sie mir die Details von Gerät 123" ist und kein Fehler für den Server darstellt , ist dies eine Ausnahme für die Erwartung des Clients, dass er ein zurückerhältDeviceInfo
und sollte nicht wie gewohnt kommuniziert werden "hier ist das, wonach du gefragt hast" antwort.quelle
Sie könnten Fehler 422 Unprocessable Entity verwenden, um zu unterscheiden, dass 404 nicht gefunden wurde . 422 bedeutet, dass der Server die Anforderung versteht, aber keine ordnungsgemäße Antwort geben kann. Ich verwende diesen Code in ähnlichen Situationen.
quelle
Fehler 500 zeigt normalerweise an, dass die Anforderung ein serverseitiges Programm zum Absturz gebracht hat. In Unternehmensumgebungen werden diese Fehler wie ein Ei im Gesicht behandelt und vermieden.
Fehler 4xx sollte dem Programmierer signalisieren, dass der API-Endpunkt (Ressource) nicht vorhanden ist. Sobald der entsprechende Endpunkt erreicht ist, liegt die Fehlerbehandlung ab diesem Zeitpunkt in der Verantwortung des Programmierers der API, die ordnungsgemäß behandelt werden sollte, dh mit einer Fehlermeldung von 200 Antworten.
quelle
Obwohl das w3 feststellt, dass 404 verwendet wird, wenn keine andere Antwort zutreffend ist , ist dies nicht das, wofür eine 204-Antwort (ohne Inhalt) gut ist? Die Anforderung war vom Verarbeitungsstandpunkt aus gültig, und der Server hat die Anforderung verarbeitet und hat ein Ergebnis. Das ist ein Erfolg, der sich zu 2xx Antworten neigt. Es gab keinen Inhalt für diese bestimmte Anfrage, so dass 204 dem Benutzer mitteilt, dass an seiner Abfrage nichts falsch war, aber nichts da ist.
Sie könnten auch einen schwachen Fall machen, dass 409 (Konflikt) eine angemessene Antwort ist. Obwohl 409 am häufigsten für einen POST verwendet wird, heißt es doch
Das Nichtvorhandensein der angeforderten ID ist hier möglicherweise der Konflikt, und die Meldung, dass keine solche ID im System vorhanden ist, reicht aus, um den Konflikt zu erkennen und zu beheben.
quelle
Die anderen Antworten befassen sich damit, aber ich wollte nur darauf hinweisen, dass ein Fehler der 500er-Serie bedeutet, dass ich etwas durcheinander gebracht habe. In diesem Fall bedeutet "I" die API, also einen unbehandelten Serverfehler oder ähnliches. Ein Fehler der 400er-Serie bedeutet "Sie haben etwas durcheinander gebracht" - der Aufrufer der API hat etwas Falsches gesendet.
quelle
Andere Benutzer haben gültige Antworten gegeben, um herauszufinden, was zu tun ist, wenn Sie das Buch lesen möchten.
Ich würde jedoch vorschlagen, dass Sie zu viel in die RESTfulness lesen und absolut koscher in Bezug darauf sind.
REST ist ein launisches Protokoll, denn wenn Sie das Buch während der Verwendung durchgehen möchten, müssen sowohl Client als auch Server mit spezifischem Wissen über die Tatsache erstellt werden, dass sie über REST kommunizieren, was im Wesentlichen das spezifische Kommunikationsprotokoll ist used kann nicht abstrahiert werden.
Es gibt einen anderen Ansatz: Vermeiden Sie RESTfulness vollständig und verwenden Sie es nur als Kommunikationsprotokoll und sonst nichts. Dies bedeutet, dass die einzigen Antworten, die zurückgegeben werden müssen, "HTTP 200 OK" und "HTTP 500 Internal Server Error" sind, da hinsichtlich des Kommunikationsprotokolls jeder Kommunikationsversuch nur zwei Ergebnisse haben kann: Entweder war die Anforderung erfolgreich an den Server geliefert oder nicht.
Was nach der Auslieferung passiert, geht das Kommunikationsprotokoll nichts an. Nachdem der Server die Anforderung erfolgreich empfangen und mit der Verarbeitung begonnen hat, können viele Fehler auftreten. Dies sind jedoch alle anwendungsspezifischen Fehler, über die das Kommunikationsprotokoll nichts zu wissen hat. Sie sollten innerhalb der Nutzlast einer Antwort kommuniziert werden, die nach Kenntnis des Kommunikationsprotokolls vollkommen erfolgreich aussieht.
Unterm Strich würde ich also empfehlen, "HTTP 200 OK" zurückzugeben und in der Antwortnutzlast ("Antwortinhaltshauptteil" in der HTTP-Sprache) einen anwendungsspezifischen Fehlercode mit der Aufschrift "ID nicht gefunden" oder was auch immer zu verwenden.
quelle