1090 Stimmen

Ist ein Entity-Body für eine HTTP-DELETE-Anfrage erlaubt?

Bei einer HTTP-DELETE-Anfrage sollte der Anfrage-URI die zu löschende Ressource vollständig identifizieren. Ist es jedoch zulässig, zusätzliche Metadaten als Teil des Entitätskörpers der Anfrage hinzuzufügen?

8 Stimmen

In ASP.NET WebApi 2 FromBody Parameter werden für HttpDelete Endpunkte ignoriert.

7 Stimmen

Ich habe ein ähnliches Anliegen, aber mein Fall ist anders. Ich möchte einen Batch-Löschauftrag erteilen, wenn ich hundert Objekte löschen möchte. Das ist sicherlich ein großer Leistungsschub für Netze vor HTTP 2.0.

3 Stimmen

Gibt es irgendwelche Änderungen in HTTP/2?

863voto

Tomalak Punkte 320467

Die Spezifikation verbietet oder rät nicht ausdrücklich davon ab, daher würde ich sagen, dass es erlaubt ist.

Microsoft sieht das genauso (ich höre ein Raunen im Publikum), sie schreiben in dem MSDN-Artikel über die DELETE-Methode von ADO.NET Data Services Framework :

Wenn eine DELETE-Anfrage einen Entitätskörper enthält, wird dieser ignoriert [...]

Zusätzlich gibt es folgende Informationen RFC2616 (HTTP 1.1) in Bezug auf Anfragen zu sagen hat:

  • eine Entität-Körper ist nur vorhanden, wenn ein Nachricht-Körper vorhanden ist (Abschnitt 7.2)
  • das Vorhandensein eines Nachricht-Körper wird durch die Aufnahme eines Content-Length o Transfer-Encoding Kopfzeile (Abschnitt 4.3)
  • a Nachricht-Körper darf nicht enthalten sein, wenn die Spezifikation der Anfragemethode das Senden einer Entität-Körper (Abschnitt 4.3)
  • eine Entität-Körper ist ausdrücklich nur bei TRACE-Anfragen verboten, alle anderen Anfragearten sind uneingeschränkt möglich (Abschnitt 9 und insbesondere 9.8)

Für Antworten wurde dies definiert:

  • ob ein Nachricht-Körper enthalten ist, hängt sowohl von der Anfragemethode y Antwortstatus (Abschnitt 4.3)
  • a Nachricht-Körper ist in Antworten auf HEAD-Anfragen ausdrücklich untersagt (Abschnitt 9 und insbesondere 9.4)
  • a Nachricht-Körper ist in den Antworten 1xx (informativ), 204 (ohne Inhalt) und 304 (nicht geändert) ausdrücklich verboten (Abschnitt 4.3)
  • alle anderen Antworten enthalten einen Nachrichtentext, der jedoch null Länge haben kann (Abschnitt 4.3)

7 Stimmen

@Jason Auf jeden Fall. Sie könnten auch benutzerdefinierte Header verwenden, um zusätzliche Daten zu übergeben, aber warum nicht den Request Body verwenden.

124 Stimmen

Obwohl die Spezifikation nicht verbietet, dass DELETE-Anfragen einen Message-Body haben, Abschnitt 4.3 scheint darauf hinzuweisen, dass der Körper sollte von Servern ignoriert werden da es keine "definierte Semantik" gibt für DELETE Entity-Körper: "Ein Server SOLLTE bei jeder Anfrage einen Message-Body lesen und weiterleiten; wenn die Anfragemethode keine definierte Semantik für einen Entity-Body enthält, dann SOLLTE der Message-Body bei der Bearbeitung der Anfrage ignoriert werden ."

127 Stimmen

Bitte beachten Sie, dass viele Clients auch nicht in der Lage sind, ein DELETE mit einem Body zu senden. Das ist mir gerade auf Android aufgefallen.

331voto

grzes Punkte 3237

Die letzte Aktualisierung der HTTP 1.1-Spezifikation ( RFC 7231 ) erlaubt ausdrücklich einen Entity-Body in einer DELETE-Anfrage:

Eine Nutzlast innerhalb einer DELETE-Anforderungsnachricht hat keine definierte Semantik; das Senden eines Nutzlastkörpers bei einer DELETE-Anforderung könnte dazu führen, dass einige bestehende Implementierungen die Anforderung zurückweisen.

4 Stimmen

In der letzten noch nicht genehmigten Version der Spezifikation wurde diese Anforderung gestrichen. Die letzte genehmigte Version ist immer noch der oben zitierte RFC2616.

4 Stimmen

Welche Version? Version 20 hat immer noch den gleichen Wortlaut wie Version 19, die ich oben verlinkt habe: "Bodies auf DELETE-Anfragen haben keine definierte Semantik. Beachten Sie, dass das Senden eines Bodys bei einer DELETE-Anfrage einige bestehende Implementierungen dazu veranlassen könnte, die Anfrage zurückzuweisen."

13 Stimmen

Version 26 Vorschläge, die Sie einem Körper erlauben können: A payload within a DELETE request message has no defined semantics; sending a payload body on a DELETE request might cause some existing implementations to reject the request. Es gibt also eine Warnung zur Abwärtskompatibilität, die darauf hindeutet, dass die nächste Norm lauten wird: "Ja! DELETE einen Körper haben kann".

62voto

evan.leonard Punkte 969

Einige Versionen von Tomcat und Jetty scheinen einen Entity Body zu ignorieren, wenn er vorhanden ist. Das kann lästig sein, wenn Sie ihn eigentlich empfangen wollten.

3 Stimmen

Google App Engine instanziiert und übergibt eine leere Standardentität anstelle des Anfragekörpers.

0 Stimmen

59voto

Neil McGuigan Punkte 43578

Ein Grund für die Verwendung des Body in einer Löschanforderung ist die optimistische Gleichzeitigkeitskontrolle.

Sie lesen Version 1 eines Datensatzes.

GET /some-resource/1
200 OK { id:1, status:"unimportant", version:1 }

Ihr Kollege verliest Version 1 des Protokolls.

GET /some-resource/1
200 OK { id:1, status:"unimportant", version:1 }

Ihr Kollege ändert den Datensatz und aktualisiert die Datenbank, wodurch die Version auf 2 aktualisiert wird:

PUT /some-resource/1 { id:1, status:"important", version:1 }
200 OK { id:1, status:"important", version:2 }

Sie versuchen, den Datensatz zu löschen:

DELETE /some-resource/1 { id:1, version:1 }
409 Conflict

Sie sollten eine optimistische Sperrausnahme erhalten. Lesen Sie den Datensatz erneut, stellen Sie fest, dass er wichtig ist, und löschen Sie ihn vielleicht nicht.

Ein weiterer Grund für die Verwendung ist das gleichzeitige Löschen mehrerer Datensätze (z. B. in einem Raster mit Kontrollkästchen für die Zeilenauswahl).

DELETE /messages
[{id:1, version:2},
{id:99, version:3}]
204 No Content

Beachten Sie, dass jede Nachricht ihre eigene Version hat. Vielleicht können Sie mehrere Versionen mit mehreren Kopfzeilen angeben, aber bei George ist dies einfacher und viel bequemer.

Dies funktioniert in Tomcat (7.0.52) und Spring MVC (4.05), möglicherweise auch in früheren Versionen:

@RestController
public class TestController {

    @RequestMapping(value="/echo-delete", method = RequestMethod.DELETE)
    SomeBean echoDelete(@RequestBody SomeBean someBean) {
        return someBean;
    }
}

26 Stimmen

Körper in GET (und DELETE) zu haben, ist eindeutig eine Misshandlung von HTTP und REST. Es gibt andere Mechanismen für den Umgang mit der Gleichzeitigkeitskontrolle (z. B. If-Modified-Since und Etags).

31 Stimmen

Inwiefern ist es eindeutig eine Fehlbehandlung, wenn die Spezifikation den Körper in DELETE nicht verbietet?

7 Stimmen

Denn du bist nicht dazu bestimmt, irgendetwas mit deinem Körper zu tun. Siehe: stackoverflow.com/a/983458/372643

42voto

Ben Fried Punkte 2036

Nur eine Vorwarnung: Wenn Sie einen Body in Ihrer DELETE-Anfrage angeben und einen Google Cloud HTTPS Load Balancer verwenden, wird dieser Ihre Anfrage mit einem 400-Fehler zurückweisen. Ich habe meinen Kopf gegen eine Wand geschlagen und habe herausgefunden, dass Google, aus welchem Grund auch immer, denkt, dass eine DELETE-Anfrage mit einem Body eine fehlerhafte Anfrage ist.

7 Stimmen

for whatever reason - weil es in der Spezifikation so steht :P

49 Stimmen

Die Spezifikation "sagt das nicht", sie sagt nur, dass der Körper nicht speziell definiert ist. Wenn er nicht definiert ist und Sie ihn ignorieren wollen, ist das in Ordnung... ignorieren Sie ihn ruhig. Aber den Antrag rundheraus abzulehnen, erscheint extrem und unnötig.

5 Stimmen

Verlassen Sie sich nicht auf undefiniertes Verhalten. Das ist eine ziemlich gängige Best Practice.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X