Während die HTTP 1.1-Spezifikation anscheinend allow Nachrichtentexte auf DELETE Requests enthält, scheint es so Geben Sie an, dass Server diese ignorieren sollen, da für sie keine Semantik definiert ist.
4.3 Nachrichtentext
Ein Server SOLLTE bei jeder Anfrage einen Nachrichtentext lesen und weiterleiten. Wenn die Anforderungsmethode keine definierte Semantik für einen Entity-Body enthält, MUSS der Message-Body bei der Bearbeitung der Anforderung ignoriert werden.
Ich habe bereits mehrere verwandte Diskussionen zu diesem Thema in SO und darüber hinaus besprochen, darunter:
Die meisten Diskussionen scheinen zu stimmen, dass das Bereitstellen eines Nachrichtentexts bei DELETE erlaubt ist, aber im Allgemeinen nicht empfohlen wird.
Außerdem habe ich in verschiedenen HTTP-Client-Bibliotheken einen Trend festgestellt, bei dem immer mehr Verbesserungen für diese Bibliotheken protokolliert werden, um Anforderungskörper in DELETE zu unterstützen. Die meisten Bibliotheken scheinen sich zu verpflichten, wenn auch gelegentlich mit ein wenig anfänglichem Widerstand.
In meinem Anwendungsfall müssen einige erforderliche Metadaten zu einem DELETE hinzugefügt werden (z. B. der "Grund" für das Löschen sowie einige andere für das Löschen erforderliche Metadaten). Ich habe die folgenden Optionen in Betracht gezogen, von denen keine vollständig angemessen und im Einklang mit den HTTP-Spezifikationen und/oder REST - Best Practices zu sein scheint:
POST /resourceToDelete { deletemetadata }
) POST ist keine semantische Option zum Löschen. POST stellt tatsächlich die gewünschte Gegenteil Aktion dar (d. H. POST erstellt Ressourcenuntergeordnete, aber ich muss die Ressource löschen)Meine erste Präferenz wäre wahrscheinlich, den Nachrichtentext zu verwenden, die zweite gegenüber benutzerdefinierten HTTP-Headern. Wie bereits erwähnt, weisen diese Ansätze jedoch einige Nachteile auf.
Gibt es Empfehlungen oder Best Practices, die den REST/HTTP-Standards entsprechen, um die erforderlichen Metadaten in DELETE-Anforderungen aufzunehmen? Gibt es andere Alternativen, die ich nicht in Betracht gezogen habe?
Trotz einiger Empfehlungen, den Nachrichtentext nicht für DELETE-Anforderungen zu verwenden, kann dieser Ansatz in bestimmten Anwendungsfällen angemessen sein. Dies ist der Ansatz, den wir letztendlich gewählt haben, nachdem wir die anderen in den Fragen/Antworten genannten Optionen bewertet und mit den Verbrauchern des Dienstes zusammengearbeitet haben.
Obwohl die Verwendung des Nachrichtentexts nicht ideal ist, passte auch keine der anderen Optionen perfekt. Der Anfragetext DELETE ermöglichte es uns, zusätzliche Daten/Metadaten, die für die DELETE-Operation benötigt wurden, einfach und klar mit einer Semantik zu versehen.
Ich wäre immer noch offen für andere Gedanken und Diskussionen, wollte aber den Kreis dieser Frage schließen. Ich schätze alle Gedanken und Diskussionen zu diesem Thema!
Was Sie zu wollen scheinen, ist eines von zwei Dingen, von denen keines ein reines DELETE
ist:
PUT
des Löschgrundes gefolgt von einem DELETE
der Ressource. Nach dem Löschen ist der Inhalt der Ressource für niemanden mehr zugänglich. Der 'Grund' darf keinen Hyperlink zur gelöschten Ressource enthalten. Oder,state=active
bis state=deleted
mit der DELETE
Methode. Ressourcen mit dem Status "Gelöscht" werden von Ihrer Haupt-API ignoriert, können jedoch von einem Administrator oder einer Person mit Datenbankzugriff gelesen werden. Dies ist zulässig - DELETE
muss die Sicherungsdaten für eine Ressource nicht löschen, nur um die Ressource zu entfernen, die bei dieser URI verfügbar gemacht wurde.Jede Operation, die einen Nachrichtentext für eine DELETE
-Anforderung erfordert, kann in den allgemeinsten, einen POST
, um alle erforderlichen Aufgaben mit dem Nachrichtentext auszuführen, und einen DELETE
. Ich sehe keinen Grund, die Semantik von HTTP zu brechen.
In Anbetracht der Situation, die Sie haben, würde ich einen der folgenden Ansätze wählen:
resource/:id
. Sie können es für jeden Grund mit Link-Headern in der Ressource sichtbar machen (mit einem rel
-Tag, um den Grund zu identifizieren).resource/:id/canceled
. Dies ändert den Request-URI tatsächlich und ist definitiv nicht REST-konform. Auch hier können Link-Header dies auffindbar machen.Denken Sie daran, dass REST kein Gesetz oder Dogma ist. Betrachten Sie es eher als Anleitung. Wenn es also Sinn macht, die Anleitung für Ihre Problemdomäne nicht zu befolgen, tun Sie das nicht. Stellen Sie einfach sicher, dass Ihre API Verbraucher werden über die Abweichung informiert.
Ich schlage vor, dass Sie die erforderlichen Metadaten als Teil der URI-Hierarchie selbst einbeziehen. Ein Beispiel (naiv):
Wenn Sie Einträge basierend auf einem Datumsbereich löschen müssen, anstatt das Start- und Enddatum im Text oder als Abfrageparameter zu übergeben, strukturieren Sie den URI so, dass Sie die erforderlichen Informationen als Teil des URI übergeben.
z.B.
DELETE /entries/range/01012012/31122012
- Alle Einträge zwischen dem 01. Januar 2012 und dem 31. Dezember 2012 löschen
Hoffe das hilft.