Ich entwerfe eine pragmatische REST-API und bin ein wenig überlegt, wie vorhandene Entitäten einer Sammlung am besten hinzugefügt werden können. Mein Domain-Modell enthält ein Projekt mit einer Sammlung von Websites. Dies ist eine strenge Viele-zu-Viele-Beziehung, und ich muss keine Entität erstellen, die die Beziehung explizit modelliert (z. B. ProjectSite).
Meine API ermöglicht es Verbrauchern, eine vorhandene Site zu einem Projekt hinzuzufügen. Wo ich aufgehängt werde, ist, dass die einzigen Daten, die ich wirklich brauche, ProjectId und SiteId sind. Meine ursprüngliche Idee war:
1. POST myapi/projects/{projectId}/sites/{siteId}
Aber ich habe auch darüber nachgedacht
2. POST myapi/projects/{projectId}/sites
mit einer Site-Entität, die als JSON-Inhalt gesendet wurde.
Option 1 ist einfach und funktioniert, fühlt sich aber nicht richtig an. Ich habe andere Beziehungen, die diesem Muster nicht folgen können, sodass meine API inkonsistent wird.
Option 2 fühlt sich besser an, führt aber zu zwei Bedenken:
- Soll ich eine Site erstellen oder eine Ausnahme auslösen, wenn eine neue Site veröffentlicht wird (SiteId = 0)?
- Da ich zum Erstellen der Beziehung nur ProjectId und SiteId benötige, wird die Site möglicherweise mit falschen oder fehlenden Daten für andere Eigenschaften gepostet.
Eine dritte Option besteht darin, einen einfachen Endpunkt ausschließlich zum Erstellen und Löschen der Beziehung bereitzustellen. Dieser Endpunkt würde eine JSON-Nutzlast erwarten, die nur ProjectId und SiteId enthält.
Was denkst du?
quelle
Antworten:
POST ist das "Anhängen" -Verb und auch das "Verarbeiten" -Verb. PUT ist das Verb "create / update" (für bekannte Bezeichner) und scheint hier fast die richtige Wahl zu sein, da der vollständige Ziel-URI bekannt ist.
projectId
und sindsiteId
bereits vorhanden, sodass Sie nicht in eine Sammlung POSTEN müssen, um eine neue ID zu erstellen.Das Problem bei PUT ist, dass der Body die Repräsentation der Ressource sein muss, die Sie PUTting. Die Absicht hierbei ist jedoch, an die Sammlungsressource "project / sites" anzuhängen, anstatt die Site-Ressource zu aktualisieren.
Was passiert, wenn jemand eine vollständige JSON-Darstellung einer vorhandenen Site erstellt? Sollten Sie die Auflistung und das Objekt aktualisieren? Sie könnten das unterstützen, aber es hört sich so an, als wäre das nicht die Absicht. Wie du gesagt hast,
Stattdessen würde ich versuchen, das POST
siteId
in die Auflistung einzutragen , und mich auf die Eigenschaften "Anhängen" und "Verarbeiten" von POST verlassen:Da Sie die Websites sind zu modifizieren Sammlung Ressource und nicht die Website - Ressource , das ist die URI Sie wollen. Der POST kann "anhängen / verarbeiten" und das Element mit dieser ID zur Websitesammlung des Projekts hinzufügen.
Dadurch bleibt die Tür für die Erstellung brandneuer Sites für das Projekt offen, indem der JSON-Code konkretisiert und die ID weggelassen wird. "Keine ID" == "Von Grund auf neu erstellen". Wenn die Auflistungs-URI jedoch eine ID und nichts anderes erhält, ist ziemlich klar, was passieren muss.
Interessante Frage. :)
quelle
POST
anstelle vonPUT
oderPATCH
hier verwenden müssen, ist, dass Sie nicht die gesamteSite
Entität für diesites
Ressource haben. Sie haben nur die ID, die verarbeitet werden muss, um sie der Sammlung hinzuzufügen.Wir verwenden die
Patch
Methode für solche Dinge. Sie möchten ein vorhandenes Projekt ändern, um ihm eine Site hinzuzufügen.So etwas würde funktionieren
mit der Site (s) -Entität als JSON / JSONArray im Anforderungshauptteil.
Auf diese Weise können Sie bei Bedarf dieselbe URL verwenden, um verschiedene Teile des Projekts zu ändern - Ihr Code in der Implementierung muss intelligent genug sein, um diese teilweise Änderung der Ressource zu verarbeiten.
quelle
{"sites": [], "other-stuff": {}}
angibt, was gesendet wird ... Sie können dann Ihren Code verzweigen, um alle diese "subjsons" sehr einfach zu behandeln. Es hängt wirklich von Ihrem spezifischen Problem ab, aber ich würde immer noch die Verwendung von PATCH empfehlen, da es speziell für diese Art von Dingen entwickelt wurde.PATCH
auch erwartet, dass die vollständige Entität hier als Wert übergeben wird, anstatt als ID, die auf eine Entität verweist?