it-swarm.com.de

RESTful API repräsentiert das Fehlen einer Sache

Stellen Sie sich eine API vor, um festzustellen, ob eine Person ihr Geistertier ausgewählt hat. Sie können nur null oder ein Geistertier haben.

Zur Zeit:

/person/{id}/selectedSpiritAnimal

wenn sie ein Tier ausgewählt haben, werden http 200 und {selectedAnimal:mole} zurückgegeben.

wenn sie jedoch keine Auswahl haben, wird http 404 zurückgegeben.

Dies macht mein Geistertier unglücklich, da wir ein gültiges Domänenproblem darstellen - nachdem wir noch kein Geistertier ausgewählt haben - als HTTP-Fehler.

Außerdem möchten wir als Unternehmen - ähm Sprit-Animal-Hampers-R-us - wissen, wann jemand keine Auswahl hat, damit wir ihn dazu auffordern können.

Was ist hier eine bessere Antwort:

HTTP 200 und {selectedAnimal:null}

oder noch expliziter

HTTP 200 und {selectedAnimal:null, spiritAnimalSelected: false}

Oder ist es besser, einen 404 zurückzugeben? Da ähnlich wie this image has not yet been uploaded Beim Anzeigen eines Bildes online eine 404 wäre. this person has not selected a spirit animal Könnte eine 404 sein


Diese Frage wurde als Duplikat vorgeschlagen, aber diese Frage adressiert eine ansonsten gültige URL, die angefordert wird, wenn die Anwendung so konfiguriert wurde, dass die von dieser URL dargestellte Änderung nicht zugelassen wird.

Während ich hier sehe, wie man eine Ressource darstellt, bei der das Fehlen der Ressource von Bedeutung ist. Das heißt, Es ist gültig, dass der Client die URL anfordert, und die Antwort lautet, dass Sie die Ressource erfolgreich angefordert haben, die das Fehlen einer Sache darstellt.

Dies ist also keine 'Geschäftslogik', sondern ein Umstand, in dem das Fehlen einer Sache eine Bedeutung hat (es kann sein, dass viele meiner Kollegen argumentieren, dass 404 immer noch korrekt ist), aber ich bin mir nicht sicher, wie ich das dem zuordnen soll spez.


Sehr schwer eine Antwort zu finden. Ich habe meine Meinung mehrmals über das Gespräch hier und das Gespräch bei der Arbeit geändert.

Die Sache, die es für mich hier regelt, ist, dass die Spezifikation besagt, dass ein 4xx ist, wenn der Client einen Fehler gemacht hat . In diesem Fall wurde dem Client mitgeteilt, dass er eine Antwort von der URL "selectedSpiritAnimal" erwarten soll, sodass kein Fehler aufgetreten ist.

Meine Kollegen sind sich einig, dass dies ein Symptom für ein schlechtes API-Design ist

Es wäre wahrscheinlich besser, wenn wir einfach/person/{id} anfordern und eine Reihe von Linkbeziehungen für die Person zurückgeben ... dann, wenn Sie nicht den Link/selectedSpiritAnimal erhalten (wenn eine Person keine Auswahl hat), sondern Sie Nennen wir es trotzdem, dann macht ein 404 Sinn. Oder dass Sie Teilantworten implementieren und/person/{id} ein vollständigeres Dokument zurückgeben lassen, es sei denn, der Client fordert eine Teilmenge der Daten an

19
Paul D'Ambra

HTTP 4xx-Codes sind wahrscheinlich nicht die richtige Wahl für dieses Szenario. Sie geben an, dass Null-Geist-Tiere ein gültiger Zustand sind, und die API-Route person/{id}/selectedSpiritAnimal wird berücksichtigen, ob die Person id eine hat oder nicht.

HTTP 4xx-Antworten sind für den Fall reserviert, dass ein Client in der Anforderung etwas falsch gemacht hat (siehe w3s Archiv der ursprünglichen Spezifikation ). Der Kunde stellt jedoch eine gültige Anfrage, unabhängig davon, ob die Person id ein Geistertier hat oder nicht.

Daher neige ich zu den zweiten Lösungen, indem ich einen ordnungsgemäß formatierten JSON-Body in der Antwort und einen HTTP 2xx-Code verwende.

Wenn Sie nun eine solche Anfrage erhalten und sich herausstellt, dass die Person id nicht existiert, ist ein 4xx-Code sinnvoller.

24
Brandon Arnold

Lassen Sie mich Ihnen das Richardson Maturity Model vorstellen.

Ihr Problem ist, dass Sie zwei Ressourcen als eine darstellen, wobei Sie wirklich zwei Ressourcen haben sollten, deren Beziehung durch Hypermedia angezeigt wird. Die Verwendung von Hypermedien zur Beschreibung von Beziehungen ist die glorreiche Stufe 3 der Ruhe.

Ihre Person sollte unter der URI /person/{id} Leben und das Tier sollte unter /spiritanimal/{id} Leben. Die Person sollte angeben, dass sie ein Geistertier hat, indem sie einen Link zum Tier verwendet.

Stellen wir uns eine Person namens Bob vor, die die ID 123 und ein Einhorn-Geistertier hat.

GET /person/123

würde zurückkehren;

{
  "name": "Bob",
  "links": [
    {
      "rel": "spiritanimal",
      "uri": "/spiritanimals/789"
    }
  ]
}

Jetzt weiß jeder, der Person 123 liest, dass er ein Geistertier hat und die URI hat, unter der er weitere Informationen darüber erhalten kann.

GET /spitiranimal/789

könnte zurückkehren

{
  "type": "Unicorn"
}

Stellen wir uns nun eine Person namens Fred vor, die die ID 456 hat und kein Geistertier hat.

GET /person/456

würde zurückkehren;

{
  "name": "Fred",
  "links": [
  ]
}

Jetzt wird jeder, der Person 456 liest, wissen, dass er kein Geistestier hat, da es keine Verbindung gibt. Es ist nicht erforderlich, einen HTTP-Statuscode zu verwenden, um das Fehlen einer Beziehung darzustellen.

24
Qwerky

Dies ist die geeignete URL, um Geistertiere zu erhalten. Daher ist ein 404-Fehler unangemessen. 404 dient zur Darstellung eines technischen Problems, nicht eines logischen Problems.

Die geeignete Lösung besteht darin, http 200 und {"selectedAnimal": null} Zurückzugeben.

Sie sollten eine separate Webmethode /person/{id}/hasSelectedSpiritAnimal Haben, die {"isSpiritAnimalSelected": false} Zurückgibt. Hinter den Kulissen kann es sein, dass es dieselben Methodenaufrufe ausführt oder nicht und nur false zurückgibt, wenn null, aber das muss entschieden werden, nicht der konsumierende Code.

Es ist besser, das Kombinieren zu getrennten Abfragen in einer Webmethode ohne zwingenden Grund zu vermeiden, selbst wenn die Abfragen eng miteinander verbunden sind.

1
TheCatWhisperer

Was Ihr Endpunkt darstellt, ist nicht nur ein Tier. es ist ein Tier oder es fehlt Es ist ein Wert, der am besten durch ein Optional/Maybe/Nullable/etc. dargestellt wird.

So können legitime Werte (wie in 200 OK) sein:

  • {'animal': <some animal>, 'selected': true}
  • {'animal': null, 'selected': false}

Ich könnte mir vorstellen, dass die Methode DELETE, wenn sie auf den Endpunkt angewendet wird, 'selected' Wieder auf false setzen kann, dh das ausgewählte Tier deaktiviert.

Sie können hier natürlich die Taste 'selected' Ablegen. Sie wird nur zur Verdeutlichung angezeigt. string vs null reicht für die Unterscheidung.

1
9000

Sie sollten 404 verwenden.

Der Statuscode 404 (Nicht gefunden) gibt an, dass der Origin-Server keine aktuelle Darstellung für die Zielressource gefunden hat

RFC7231

HTTP/1.1 200 OK
Content-Type: application/json
Date: Mon, 25 Sep 2017 00:00:00 GMT

"mole"

HTTP/1.1 404 Not Found
Content-Type: text/plain
Date: Mon, 25 Sep 2017 00:00:00 GMT

this person has not selected a spirit animal

Da Sie eine Programmierschnittstelle und keine Benutzerschnittstelle erstellen, ist der 404-Text optional.

Ich bevorzuge dies, weil ich Standardprotokolle so sehr wie möglich bevorzuge. HTTP hat eine Möglichkeit, Nichtexistenz darzustellen, und das würde ich verwenden.

BEARBEITEN: Angenommen, Sie haben eine Funktion hinzugefügt, mit der Benutzer auswählen können, ob sie ihre Geistertiere teilen möchten, und jemand hat sie nicht geteilt. Würden Sie 200 OK null oder 200 OK "Unauthorized Zurückgeben? Oder würden Sie den Standard 401 Unauthorized/403 Forbidden verwenden? Dies scheint direkt analog dazu zu sein, überhaupt keine zu wählen.


Wenn Sie alternativ 200 OK + JSON verwenden möchten, sollten Sie null zurückgeben.

HTTP/1.1 200 OK
Content-Type: application/json
Date: Mon, 25 Sep 2017 00:00:00 GMT

"mole"

HTTP/1.1 200 OK
Content-Type: application/json
Date: Mon, 25 Sep 2017 00:00:00 GMT

null

Halte die Dinge sauber. Erstellen Sie nur bei Bedarf weitere Verpackungen.

0
Paul Draper