Manipulation der Massensammlung über eine REST-API (RESTful)

73

Ich möchte einige Ratschläge zum Entwerfen einer REST-API, mit der Clients eine große Anzahl von Objekten effizient zu einer Sammlung hinzufügen / daraus entfernen können.

Über die API müssen Clients in der Lage sein, Elemente zur Sammlung hinzuzufügen und Elemente daraus zu entfernen sowie vorhandene Elemente zu bearbeiten. In vielen Fällen möchte der Client die Sammlung in großen Mengen aktualisieren, z. B. 1000 Elemente hinzufügen und 500 verschiedene Elemente löschen. Es scheint, dass der Client dies in einer einzigen Transaktion mit dem Server tun sollte, anstatt 1000 separate POST-Anforderungen und 500 DELETEs zu benötigen.

Hat jemand Informationen zu den Best Practices oder Konventionen, um dies zu erreichen?

Mein derzeitiger Gedanke ist, dass man in der Lage sein sollte, ein Objekt zu PUTEN, das die Änderung des Sammlungs-URI darstellt, aber dies scheint im Widerspruch zum HTTP 1.1-RFC zu stehen , was darauf hindeutet, dass die in einer PUT-Anforderung gesendeten Daten unabhängig von der interpretiert werden sollten Daten bereits am URI vorhanden. Dies bedeutet, dass der Client auf einmal eine vollständige Beschreibung des neuen Status der Sammlung senden muss, die möglicherweise sehr viel größer als die Änderung oder sogar größer ist, als der Client bei der Anforderung wissen würde.

Natürlich würde ich gerne bei Bedarf vom RFC abweichen, würde dies aber lieber auf herkömmliche Weise tun, wenn eine solche Konvention existiert.

Mattwynne
quelle
Steuern Sie die Clients mithilfe Ihrer API oder müssen Sie vorhandene Clientprodukte unterstützen? Mit anderen Worten: Können Sie die Semantik von Anforderungsentitäten frei definieren?
Mkoeller

Antworten:

63

Vielleicht möchten Sie sich die Änderungsaufgabe als eine Ressource für sich vorstellen. Sie setzen also wirklich ein einzelnes Objekt ein, bei dem es sich um ein Bulk Data Update-Objekt handelt. Vielleicht hat es einen Namen, einen Eigentümer und einen großen Blob aus CSV, XML usw., der analysiert und ausgeführt werden muss. Im Fall von CSV möchten Sie möglicherweise auch identifizieren, welche Art von Objekten in den CSV-Daten dargestellt werden.

Listen Sie Jobs auf, fügen Sie einen Job hinzu, zeigen Sie den Status eines Jobs an, aktualisieren Sie einen Job (wahrscheinlich, um ihn zu starten / zu stoppen), löschen Sie einen Job (stoppen Sie ihn, wenn er ausgeführt wird) usw. Diese Vorgänge lassen sich problemlos einem REST-API-Design zuordnen.

Sobald Sie dies eingerichtet haben, können Sie problemlos verschiedene Datentypen hinzufügen, die Ihr Massendaten-Updater verarbeiten kann, möglicherweise sogar in derselben Aufgabe zusammenmischen. Es ist nicht erforderlich, dass dieselbe API für jede Art von Dingen, die Sie importieren möchten, in Ihrer gesamten App dupliziert wird.

Dies eignet sich auch sehr leicht für eine Implementierung von Hintergrundaufgaben. In diesem Fall möchten Sie wahrscheinlich Felder zu den einzelnen Aufgabenobjekten hinzufügen, mit denen der API-Client angeben kann, wie sie benachrichtigt werden sollen (eine URL, die Sie abrufen sollen, wenn dies erledigt ist, oder ihnen eine E-Mail senden usw.). .

Jamie Flournoy
quelle
2
Dies muss als Antwort überprüft werden!
HDave
2
Gute Antwort. Wenn Sie eine Operation auf eine große Anzahl von Ressourcen anwenden möchten und diese mithilfe von Filterbedingungen auswählen, übergeben Sie möglicherweise ein Objekt mit den Filterbedingungen an die Änderungsaufgabe.
Ameba Spugnosa
2
Obwohl es vernünftig ist, "gesprächige" DELETEs zu vermeiden, fällt es in die RPC-Mentalität zurück ... Vielleicht ist es möglich, die Sammlung abzurufen, alle Dinge zu entfernen, die gelöscht werden sollen, und dann die Sammlung zu platzieren (unter Verwendung des Antwortstatus 409, um die Rennbedingungen zu erkennen mit gleichzeitigen Modifikatoren). Die Machbarkeit verringert sich, wenn das GET ausgelagert wird. In diesem Fall ist PATCH wahrscheinlich die richtige Alternative.
delitescere
9

Ja, PUT erstellt / überschreibt, wird jedoch nicht teilweise aktualisiert.

Wenn Sie eine teilweise Aktualisierungssemantik benötigen, verwenden Sie PATCH. Siehe http://greenbytes.de/tech/webdav/draft-dusseault-http-patch-14.html .

Julian Reschke
quelle
Das macht für mich am meisten Sinn. Nach einigen Stunden im Internet scheint dies jedoch kein allgemeiner Standpunkt zu sein. Die meisten Entwickler scheinen zu glauben, dass PATCH für eine Sammlung keine Bedeutung hat.
Mark Rucker
2

Sie sollten AtomPub verwenden . Es wurde speziell für die Verwaltung von Sammlungen über HTTP entwickelt. Möglicherweise gibt es sogar eine Implementierung für die Sprache Ihrer Wahl.

dowski
quelle
3
Tatsächlich definiert AtomPub nur das Hinzufügen und Entfernen einzelner Elemente zu einer Sammlung. Daher würde ich das nicht als "speziell für die Verwaltung von Sammlungen konzipiert" bezeichnen.
Julian Reschke
2

Zumindest für die POSTs scheint es möglich zu sein, dass Sie in der Lage sein sollten, auf eine Listen-URL zu POSTEN und dass der Hauptteil der Anforderung eine Liste neuer Ressourcen anstelle einer einzelnen neuen Ressource enthält.

Hank Gay
quelle
1

Soweit ich weiß, bedeutet REST REpresentational State Transfer, daher sollten Sie den Status vom Client auf den Server übertragen.

Wenn dies bedeutet, dass zu viele Daten hin und her gehen, müssen Sie möglicherweise Ihre Darstellung ändern. Eine collectionChange-Struktur würde funktionieren, mit einer Reihe von Löschungen (nach ID) und Ergänzungen (mit eingebetteten vollständigen XML-Darstellungen), die an eine URL der Bearbeitungsschnittstelle gesendet werden. Die Schnittstellenimplementierung kann eine eigene Methode für das Löschen und Hinzufügen serverseitig auswählen.

Die reinste Version wäre wahrscheinlich, die Elemente nach URL zu definieren, und die Sammlung enthält eine Reihe von URLs. Die neue Sammlung kann nach Änderungen durch den Client PUT sein, gefolgt von einer Reihe von PUTs der hinzugefügten Elemente und möglicherweise einer Reihe von Löschungen, wenn Sie die Elemente tatsächlich vom Server entfernen möchten, anstatt sie nur aus dieser Liste zu entfernen.

Phil H.
quelle
0

Sie können eine Metadarstellung vorhandener Sammlungselemente einführen, bei denen nicht der gesamte Status übertragen werden muss. In einem abstrakten Code könnte Ihr Update also folgendermaßen aussehen:

{vorhandene Elemente 1-100}
{neues Element foo mit den Werten "bar", "baz"}
{vorhandenes Element 105}
{neues Element foobar mit den Werten "bar", "foo"}
{vorhandene Elemente 110-200}

Das Hinzufügen (und Ändern) von Elementen erfolgt durch Definieren ihrer Werte, das Löschen von Elementen durch Nicht-Erwähnen der neuen Sammlung und das Neuordnen von Elementen durch Angeben der neuen Reihenfolge (sofern die Reihenfolge überhaupt gespeichert ist).

Auf diese Weise können Sie problemlos die gesamte neue Sammlung darstellen, ohne den gesamten Inhalt erneut übertragen zu müssen. Durch die Verwendung eines If-Unmodified-SinceHeaders wird sichergestellt, dass Ihre Vorstellung vom Inhalt tatsächlich mit der Idee des Servers übereinstimmt (damit Sie nicht versehentlich Elemente entfernen, von denen Sie zum Zeitpunkt der Übermittlung der Anforderung einfach nichts wussten).

Joachim Sauer
quelle
Wenn ich Ihr vorgeschlagenes Update-Format richtig verstehe, hat dies den Nachteil, dass es nicht idempotent ist, da Sie relativ (unter Verwendung von Indizes) auf Sammlungselemente verweisen - wenn das Update PUTzweimal (möglicherweise aus Versehen) auf den Server erfolgt, sind Sie es könnte mit einer beschädigten Sammlung enden; zB Element Nr. 105 wird beim zweiten Mal ein anderes Element sein als beim ersten Mal; Verschiedene Elemente 101-104 werden beim zweiten Mal gelöscht.
stakx - nicht mehr beitragen
0

Der beste Weg ist:

Pass Only Id Array of Deletable Objects from Front End Application To Web API
    2. Then You have Two Options: 
       2.1 Web API Way : Find All Collections/Entities using Id arrays and Delete in API , but you need to take care of Dependant entities like Foreign Key Relational Table Data too
     2.2. Database Way : Pass Ids to your database side, find all records in Foreign Key Tables and Primary Key Tables and Delete in same order i.e. F-Key Table records then P-Key Table records
Shyam Sundar Singh Tomar
quelle