Wie passt eine REST-API für eine befehls- / aktionsbasierte Domäne?

24

In diesem Artikel behauptet der Autor, dass

Manchmal ist es erforderlich, eine Operation in der API verfügbar zu machen, die von Natur aus nicht REST-konform ist.

und das

Wenn eine API zu viele Aktionen enthält, ist dies ein Hinweis darauf, dass sie entweder mit einem RPC-Standpunkt entworfen wurde, anstatt RESTful-Prinzipien zu verwenden, oder dass die betreffende API naturgemäß besser für ein RPC-Modell geeignet ist.

Dies spiegelt wider, was ich auch anderswo gelesen und gehört habe.

Ich finde das jedoch ziemlich verwirrend und möchte die Sache besser verstehen.

Beispiel I: Herunterfahren einer VM über eine REST-Schnittstelle

Ich denke, es gibt zwei grundverschiedene Möglichkeiten, ein Herunterfahren einer VM zu modellieren. Jeder Weg mag ein paar Variationen haben, aber konzentrieren wir uns vorerst auf die grundlegendsten Unterschiede.

1. Patchen Sie die state -Eigenschaft der Ressource

PATCH /api/virtualmachines/42
Content-Type:application/json  

{ "state": "shutting down" }

(Alternativ PUTauf der Subressource /api/virtualmachines/42/state.)

Die VM wird im Hintergrund heruntergefahren und zu einem späteren Zeitpunkt, je nachdem, ob das Herunterfahren erfolgreich ist oder nicht, wird der Status möglicherweise intern mit "Ausschalten" aktualisiert.

2. PUT oder POST für die Eigenschaft actions der Ressource

PUT /api/virtualmachines/42/actions
Content-Type:application/json  

{ "type": "shutdown" }

Das Ergebnis ist genau das gleiche wie im ersten Beispiel. Der Status wird so aktualisiert, dass er sofort "herunterfährt" und eventuell "ausschaltet".

Sind beide Designs RESTful?

Welches Design ist besser?

Beispiel II: CQRS

Was ist, wenn wir eine CQRS-Domäne mit vielen solchen "Aktionen" (auch als Befehle bezeichnet) haben, die möglicherweise zu Aktualisierungen mehrerer Aggregate führen oder nicht auf CRUD-Operationen für konkrete Ressourcen und Subressourcen abgebildet werden können?

Sollten wir versuchen, so viele Befehle wie möglich zu modellieren, die mit Concrete erstellt oder auf konkreten Ressourcen aktualisiert werden (gemäß dem ersten Ansatz aus Beispiel I), und im Übrigen "Aktionsendpunkte" verwenden?

Oder sollten wir alle Befehle Aktionsendpunkten zuordnen (wie im zweiten Ansatz von Beispiel I)?

Wo sollen wir die Grenze ziehen? Wann wird das Design weniger RUHIG?

Passt ein CQRS-Modell besser zu einer RPC-ähnlichen API?

Nach dem oben zitierten Text ist es, wie ich es verstehe.

Wie Sie meinen vielen Fragen entnehmen können, bin ich etwas verwirrt über dieses Thema. Können Sie mir helfen, es besser zu verstehen?

leifbattermann
quelle
"Erstellen einer Aktion" scheint nicht REST-konform zu sein, es sei denn, die ausgeführte Aktion verfügt anschließend über eine eigene Ressourcenkennung. Andernfalls ist es sinnvoller, die Eigenschaft "state" über PATCH oder PUT zu ändern. Für den CQRS-Teil habe ich noch keine gute Antwort.
Fabian Schmengler
3
@Laiv Daran ist nichts auszusetzen. Es ist eine akademische Frage, ich möchte ein tieferes Verständnis der Sache bekommen.
Leifbattermann

Antworten:

19

Im ersten Fall (Herunterfahren von VMs) würde ich keine der OP-Alternativen für RESTful halten. Zugegeben, wenn Sie das Richardson-Reifegradmodell als Maßstab verwenden, handelt es sich bei beiden um Level 2- APIs, da sie Ressourcen und Verben verwenden.

Keiner von ihnen, obwohl die Verwendung hypermedia Kontrollen, und meiner Meinung nach , dass die einzige Art von REST ist das unterscheidet RESTful API - Design von RPC. Mit anderen Worten, bleiben Sie bei Level 1 und 2, und Sie werden in den meisten Fällen eine API im RPC-Stil haben.

Um zwei verschiedene Arten des Herunterfahrens einer VM zu modellieren, würde ich die VM selbst als Ressource verfügbar machen, die (unter anderem) Links enthält:

{
    "links": [{
        "rel": "shut-down",
        "href": "/vms/1234/fdaIX"
    }, {
        "rel": "power-off",
        "href": "/vms/1234/CHTY91"
    }],
    "name": "Ploeh",
    "started": "2016-08-21T12:34:23Z"
}

Wenn ein Client das System herunterfahren möchte Ploeh VM , muss er der Verknüpfung mit dem shut-downBeziehungstyp folgen . (Normalerweise verwenden Sie, wie im RESTful Web Services-Kochbuch beschrieben , ein IRI oder ein ausführlicheres Identifikationsschema für Beziehungstypen, aber ich habe mich dafür entschieden, das Beispiel so einfach wie möglich zu halten.)

In diesem Fall gibt es nur wenige andere Informationen, die für die Aktion erforderlich sind. Der Client sollte daher einfach einen leeren POST für die URL in den hreffolgenden Bereichen erstellen :

POST /vms/1234/fdaIX HTTP/1.1

(Da diese Anforderung keinen Textkörper hat, ist es verlockend, dies als GET-Anforderung zu modellieren. GET-Anforderungen sollten jedoch keine beobachtbaren Nebenwirkungen haben, sodass der POST korrekter ist.)

Wenn ein Client die VM ausschalten möchte, folgt er power-offstattdessen dem Link.

Mit anderen Worten, die Beziehungstypen der Links bieten Vorteile , die auf Absichten hinweisen. Jeder Beziehungstyp hat eine bestimmte semantische Bedeutung. Aus diesem Grund sprechen wir manchmal über das Semantic Web .

Um das Beispiel so klar wie möglich zu halten, habe ich die URLs in jedem Link absichtlich verdeckt. Wenn der Hosting-Server die eingehende Anforderung empfängt, weiß er, dass fdaIXdies Herunterfahren und CHTY91bedeutet Ausschalten .

Normalerweise würde ich die Aktion nur in der URL selbst kodieren, so dass die URLs wären /vms/1234/shut-down und /vms/1234/power-offbeim Unterrichten verwischt dies die Unterscheidung zwischen Beziehungstypen (Semantik) und URLs (Implementierungsdetails).

Je nachdem, welche Kunden Sie haben, können Sie in Betracht ziehen , RESTful-URLs nicht hackbar zu machen .

CQRS

Wenn es um CQRS geht, sind sich Greg Young und Udi Dahan unter anderem einig, dass CQRS keine Top-Level-Architektur ist . Daher wäre ich vorsichtig, wenn ich eine RESTful-API zu CQRS-ähnlich machen würde, da dies bedeuten würde, dass Clients Teil Ihrer Architektur werden.

Die treibende Kraft hinter einer echten (Level 3) RESTful-API ist häufig, dass Sie Ihre API weiterentwickeln möchten, ohne Clients zu brechen und ohne die Kontrolle über Clients zu haben. Wenn das Ihre Motivation ist, wäre CQRS nicht meine erste Wahl.

Mark Seemann
quelle
Meinen Sie, dass die ersten Beispiele beide nicht REST-konform sind, weil sie keine Hypermedia-Steuerelemente verwenden? Aber ich habe nicht einmal Antworten gepostet, sondern nur die URLs und Textkörper der Anfragen.
Leifbattermann
4
@leifbattermann Sie sind nicht RESTful, weil sie den Nachrichtentext verwenden, um Absichten zu kommunizieren. das ist eindeutig RPC. Wenn Sie Links verwendet haben, um zu diesen Ressourcen zu gelangen, warum sollten Sie dann die Absicht über den Körper kommunizieren?
Mark Seemann
Das macht Sinn. Warum schlagen Sie einen POST vor? Ist die Handlung nicht idempotent? Wie können Sie Ihrem Client auf jeden Fall mitteilen, welche HTTP-Methode er verwenden soll?
Leifbattermann
2
@ guillaume31 kommt DELETEmir komisch vor, weil nach dem herunterfahren die vm nur noch im zustand "power off" (oder so) existieren wird.
Leifbattermann
1
Die Ressource muss eine VM nicht zeitnah widerspiegeln, sondern kann eine Ausführungsinstanz davon darstellen.
Guillaume31
6

Herunterfahren einer VM über eine REST-Schnittstelle

Dies ist tatsächlich ein ziemlich berühmtes Beispiel, das 2009 von Tim Bray angeführt wurde .

Roy Fielding, der das Problem diskutierte, teilte diese Beobachtung :

Ich persönlich bevorzuge Systeme, die den überwachten Status (wie den Energiestatus) als nicht bearbeitbar behandeln.

Kurz gesagt, Sie haben eine Informationsressource, die eine aktuelle Darstellung des überwachten Zustands zurückgibt. Diese Darstellung kann einen Hypermedien-Link zu einem Formular enthalten , das eine Änderung dieses Status anfordert, und das Formular verfügt über einen weiteren Link zu einer Ressource, die (jede) Änderungsanforderung verarbeitet.

Seth Ladd hatte die wichtigsten Einsichten in das Problem

Wir haben Running von einem einfachen Zustand einer Person zu einem echten Nomen gemacht, das erstellt, aktualisiert und besprochen werden kann.

Führen Sie dies zurück, um die Computer neu zu starten. Ich würde argumentieren, dass Sie nach / vdc / 434 / cluster / 4894 / server / 4343 / reboots POSTEN würden. Sobald Sie gepostet haben, haben Sie einen URI, der diesen Neustart darstellt, und Sie können ihn für Statusaktualisierungen abrufen. Durch die Magie des Hyperlinks wird die Darstellung des Neustarts mit dem Server verknüpft, der neu gestartet wird.

Ich denke, URI-Speicherplatz zu prägen ist billig und URIs sind noch billiger. Erstellen Sie eine Sammlung von Aktivitäten, die als Substantive und als POST, PUT und DELETE away modelliert sind!

RESTvolles Programmieren ist Vogons Bürokratie im Webmaßstab. Wie macht man etwas RESTful? Erfinde dafür neue Papiere und digitalisiere die Papiere.

In einer etwas ausgefalleneren Sprache definieren Sie das Domänenanwendungsprotokoll für "Herunterfahren einer VM" und identifizieren die Ressourcen, die Sie zum Anzeigen / Implementieren dieses Protokolls benötigen

Schauen Sie sich Ihre eigenen Beispiele an

PATCH /api/virtualmachines/42
Content-Type:application/json  

{ "state": "shutting down" }

Das ist ok; Sie behandeln die Anfrage selbst nicht wirklich als separate Informationsressource, können sie aber dennoch verwalten.

Sie haben ein wenig in Ihrer Darstellung der Änderung verpasst.

Mit PATCH enthält die beigefügte Entität jedoch eine Reihe von Anweisungen, die beschreiben, wie eine Ressource, die sich derzeit auf dem Ursprungsserver befindet, geändert werden sollte, um eine neue Version zu erstellen.

Der JSON-Patch- Medientyp formatiert beispielsweise Anweisungen, als ob Sie ein JSON-Dokument direkt ändern würden

[
    { "op": "replace", "path": "state", "value": "shutting down" }
]

In Ihrer Alternative ist die Idee nah, aber nicht offensichtlich richtig. PUTist eine vollständige Ersetzung des Status der Ressource in der Ziel-URL , sodass Sie wahrscheinlich keine Schreibweise wählen würden, die wie eine Sammlung aussieht, als Ziel einer Darstellung einer einzelnen Entität.

POST /api/virtualmachines/42/actions

Stimmt mit der Fiktion überein, dass wir eine Aktion an eine Warteschlange anhängen

PUT /api/virtualmachines/42/latestAction

Steht im Einklang mit der Fiktion, dass wir das Endelement in der Warteschlange aktualisieren; Es ist ein bisschen komisch, das so zu machen. Das Prinzip der geringsten Überraschung empfiehlt, jedem PUT eine eigene eindeutige Kennung zuzuweisen, anstatt sie alle an einem Ort zu platzieren und mehrere Ressourcen gleichzeitig zu ändern.

Beachten Sie, dass es REST im Hinblick auf die Schreibweise von URI-REST egal ist. /cc719e3a-c772-48ee-b0e6-09b4e7abbf8bist für REST ein perfekter URI. Die Lesbarkeit ist wie bei Variablennamen ein besonderes Anliegen. Die Verwendung von Schreibweisen, die mit RFC 3986 übereinstimmen , macht die Menschen viel glücklicher.

CQRS

Was ist, wenn wir eine CQRS-Domäne mit vielen solchen "Aktionen" (auch als Befehle bezeichnet) haben, die möglicherweise zu Aktualisierungen mehrerer Aggregate führen oder nicht auf CRUD-Operationen für konkrete Ressourcen und Subressourcen abgebildet werden können?

Greg Young über CQRS

CQRS ist ein sehr einfaches Muster, das viele Möglichkeiten für eine Architektur eröffnet, die es sonst möglicherweise nicht gibt. CQRS ist keine eventuelle Konsistenz, es ist kein Eventing, es ist kein Messaging, es gibt keine getrennten Modelle zum Lesen und Schreiben und es wird auch kein Event-Sourcing verwendet.

Wenn die meisten Leute über CQRS sprechen, sprechen sie wirklich über das Anwenden des CQRS-Musters auf das Objekt, das die Dienstgrenze der Anwendung darstellt.

Angesichts der Tatsache, dass Sie im Kontext von HTTP / REST über CQRS sprechen, ist es vernünftig anzunehmen, dass Sie in diesem letzteren Kontext arbeiten. Lassen Sie uns also fortfahren.

Dieser ist überraschenderweise sogar einfacher als Ihr vorheriges Beispiel. Der Grund dafür ist einfach: Befehle sind Nachrichten .

Jim Webber beschreibt HTTP als das Anwendungsprotokoll eines Büros aus den 1950er Jahren. Die Arbeit wird erledigt, indem Nachrichten entgegengenommen und in den Posteingang gestellt werden. Die gleiche Idee gilt - wir erhalten eine leere Kopie eines Formulars, füllen es mit den uns bekannten Einzelheiten aus und liefern es aus. Ta da

Sollten wir versuchen, so viele Befehle wie möglich zu modellieren, die mit Concrete erstellt oder auf konkreten Ressourcen aktualisiert werden (gemäß dem ersten Ansatz aus Beispiel I), und im Übrigen "Aktionsendpunkte" verwenden?

Ja, sofern es sich bei den "konkreten Ressourcen" eher um Nachrichten als um Entitäten im Domänenmodell handelt.

Schlüsselidee: Ihre REST-API ist immer noch eine Schnittstelle . Sie sollten in der Lage sein, das zugrunde liegende Modell zu ändern, ohne dass Clients die Nachrichten ändern müssen. Wenn Sie ein neues Modell freigeben, geben Sie eine neue Version Ihrer Web-Endpunkte frei, die wissen, wie Sie Ihr Domänenprotokoll verwenden und auf das neue Modell anwenden.

Passt ein CQRS-Modell besser zu einer RPC-ähnlichen API?

Nicht wirklich - insbesondere Web-Caches sind ein hervorragendes Beispiel für ein "schließlich konsistentes Lesemodell". Indem Sie jede Ihrer Ansichten unabhängig adressierbar machen und dabei jeweils eigene Caching-Regeln festlegen, erhalten Sie eine Reihe kostenloser Skalierungsfunktionen. Es gibt relativ wenig Anziehungskraft auf einen exklusiven RPC-Ansatz zum Lesen.

Für Schreibvorgänge ist dies eine schwierige Frage: Das Senden aller Befehle an einen einzelnen Handler an einem einzelnen Endpunkt oder an eine einzelne Familie von Endpunkten ist mit Sicherheit einfacher . Bei REST geht es mehr darum, wie Sie feststellen, dass sich der Endpunkt auf dem Client befindet.

Das Behandeln einer Nachricht als eine eigene, eindeutige Ressource hat den Vorteil, dass Sie PUT verwenden können, und macht die zwischengeschalteten Komponenten darauf aufmerksam, dass die Behandlung der Nachricht idempotent ist, sodass sie in bestimmten Fällen der Fehlerbehandlung teilnehmen können . (Hinweis: Wenn die Ressourcen aus Sicht der Clients unterschiedliche URIs aufweisen, handelt es sich um unterschiedliche Ressourcen. Die Tatsache, dass möglicherweise alle denselben Anforderungsbehandlungscode auf dem Ursprungsserver haben, ist ein Implementierungsdetail, das von der Uniform verborgen wird Schnittstelle).

Fielding (2008)

Ich sollte auch bemerken, dass das oben Genannte noch nicht vollständig RESTful ist, zumindest wie ich den Begriff benutze. Alles, was ich getan habe, ist die Beschreibung der Serviceschnittstellen, die nicht mehr sind als jeder RPC. Um es REST-fähig zu machen, müsste ich Hypertext hinzufügen, um den Service einzuführen und zu definieren, zu beschreiben, wie das Mapping mithilfe von Formularen und / oder Link-Vorlagen durchgeführt wird, und Code bereitstellen, um die Visualisierungen auf nützliche Weise zu kombinieren.

VoiceOfUnreason
quelle
2

Sie können 5 Medientypebenen verwenden , um den Befehl im Headerfeld für den Inhaltstyp der Anforderung anzugeben.

In dem VM-Beispiel wäre es etwas in diese Richtung

PUT /api/virtualmachines/42
Content-Type:application/json;domain-model=PowerOnVm

> HTTP/1.1 201 Created
Location: /api/virtualmachines/42/instance

Dann

DELETE /api/virtualmachines/42/instance
Content-Type:application/json;domain-model=ShutDownVm

Oder

DELETE /api/virtualmachines/42/instance
Content-Type:application/json;domain-model=PowerOffVm

Siehe https://www.infoq.com/articles/rest-api-on-cqrs

guillaume31
quelle
Seien Sie gewarnt, 5LMT war eine vorgeschlagene Lösung und wird von Standards nicht unterstützt . Ich bin zuvor auf den CQRS- Artikel gestoßen und habe viel daraus gelernt.
Peter L
1

Das Beispiel im verlinkten Artikel basiert auf der Idee, dass das Starten und Herunterfahren der Maschine nicht durch Änderungen des Status der modellierten Ressourcen, sondern durch Befehle gesteuert werden muss. Letzteres ist so ziemlich das, was REST lebt und atmet. Eine bessere Modellierung der VM erfordert einen Blick darauf, wie das reale Gegenstück funktioniert und wie Sie als Mensch damit interagieren würden. Dies ist langwierig, aber ich denke, es gibt einen guten Einblick in die Art des Denkens, die für eine gute Modellierung erforderlich ist.

Es gibt zwei Möglichkeiten, den Energiezustand des Computers auf meinem Schreibtisch zu steuern:

  • Netzschalter: Unterbricht sofort den Stromfluss zur Stromversorgung, wodurch der gesamte Computer plötzlich ungeordnet zum Stillstand kommt.
  • An / aus Schalter: Weist die Hardware an, der Software mitzuteilen, dass etwas außerhalb alles herunterfahren soll. Die Software fährt ordnungsgemäß herunter, benachrichtigt die Hardware darüber und signalisiert der Stromversorgung, dass sie in den Standby-Zustand wechseln kann. Wenn der Netzschalter eingeschaltet ist, das Gerät ausgeführt wird und die Software nicht auf das Abschaltsignal reagieren kann, wird das System erst heruntergefahren, wenn ich den Netzschalter ausschalte. (Eine VM verhält sich genauso. Wenn das Abschaltsignal von der Software ignoriert wird, läuft die Maschine weiter. Ich muss das Ausschalten erzwingen.) Wenn ich die Maschine neu starten möchte, muss ich es tun Schalten Sie den Netzschalter wieder ein und drücken Sie die Ein- / Aus-Taste. (Viele Computer haben die Möglichkeit, durch langes Drücken des Netzschalters direkt in den Standby-Zustand zu wechseln.) aber dieses Modell benötigt das nicht wirklich.) Diese Taste kann wie ein Kippschalter behandelt werden, da das Drücken zu einem unterschiedlichen Verhalten führt, je nachdem, in welchem ​​Zustand es gedrückt wird. Wenn der Netzschalter ausgeschaltet ist, hat das Drücken dieser Taste absolut nichts zu bedeuten.

Für eine VM können beide als Lese- / Schreib-Boolesche Werte modelliert werden:

  • power- Wenn in geändert true, passiert nichts anderes als eine Notiz, dass der Schalter in diesen Zustand versetzt wurde. Bei der Änderung in falsewird der VM befohlen, sofort ausgeschaltet zu werden. Der Vollständigkeit halber passiert nichts, wenn der Wert nach einem Schreibvorgang unverändert bleibt.

  • onoff- Wenn auf geändert true, passiert nichts, wenn dies der Fall powerist false, wird die VM zum Starten aufgefordert. Wenn auf geändert false, geschieht nichts, wenn dies der Fall powerist false. Andernfalls wird die VM angewiesen, die Software zu benachrichtigen, damit sie ordnungsgemäß heruntergefahren wird. Anschließend wird die VM darüber informiert, dass sie in den ausgeschalteten Zustand versetzt werden kann. Der Vollständigkeit halber macht ein unverändertes Schreiben nichts.

Mit all dem kommt die Erkenntnis, dass es eine Situation gibt, in der der Zustand der Maschine nicht den Zustand der Schalter widerspiegelt, und zwar während des Herunterfahrens. powerwird immer noch sein trueund onoffwerden false, aber der Prozessor wird immer noch heruntergefahren, und dafür müssen wir eine weitere Ressource hinzufügen, damit wir erkennen können, was die Maschine tatsächlich tut:

  • running- Ein schreibgeschützter Wert, der bestimmt wird, truewann die VM ausgeführt wird und falsewann nicht, indem der Hypervisor nach seinem Status gefragt wird.

Das Ergebnis ist, dass Sie sicherstellen müssen, dass powerund onoffRessourcen festgelegt wurden , wenn eine VM gestartet werden soll true. (Sie können zulassen, dass der powerSchritt übersprungen wird, indem Sie ihn selbst zurücksetzen. Wenn Sie ihn auf setzen false, wird er truenach einem überprüfbaren Hard-Stop der VM. Ob dies eine REST-reine Sache ist, ist ein Grund für eine weitere Diskussion.) wenn Sie es wollen , ein ordnungsgemäßes Abschalten tun, legen Sie onoffauf falseund kommen später wieder , um zu sehen , ob die Maschine tatsächlich gestoppt, das setzen powerauf , falsewenn es nicht tut.

Wie in der realen Welt haben Sie immer noch das Problem, angewiesen zu werden, die VM zu starten, nachdem sie auf onoffgeändert wurde. falseDies liegt jedoch runningdaran, dass sie gerade heruntergefahren wird. Wie Sie damit umgehen, ist eine politische Entscheidung.

Blrfl
quelle
0

Sind beide Designs RESTful?

Wenn Sie also in Ruhe nachdenken möchten, vergessen Sie die Befehle. Der Client weist den Server nicht an, die VM herunterzufahren. Der Client "schließt" (bildlich gesprochen) seine Kopie der Ressourcendarstellung, indem er seinen Status aktualisiert und diese Darstellung dann auf den Server zurücksendet. Der Server akzeptiert diese neue Statusdarstellung und fährt als Nebeneffekt die VM herunter. Der Nebenwirkungsaspekt bleibt dem Server überlassen.

Es ist weniger von

Hey Server, Client hier, würde es Ihnen etwas ausmachen, die VM herunterzufahren

und mehr von

Hallo Server, Client hier, ich habe den Status der Ressourcen-VM 42 in den Status "Herunterfahren" geändert, Ihre Kopie dieser Ressource aktualisiert und dann alles getan, was Sie für angemessen halten

Als Nebeneffekt kann der Server, der diesen neuen Status akzeptiert, überprüfen, welche Aktionen er tatsächlich ausführen muss (z. B. das physische Herunterfahren von VM 42), dies ist jedoch für den Client transparent. Der Client ist von allen Aktionen unberührt, die der Server ausführen muss, um mit diesem neuen Status in Einklang zu kommen

Vergiss also die Befehle. Die einzigen Befehle sind die Verben in HTTP für die Statusübertragung. Dem Client ist es egal, wie der Server die physische VM in den Zustand des Herunterfahrens versetzt. Der Client gibt keine Befehle an den Server aus, um dies zu erreichen. Er sagt lediglich, dass dies der neue Status ist .

Dies hat den Vorteil, dass der Client in Bezug auf die Flusskontrolle vom Server entkoppelt wird. Wenn der Server später die Funktionsweise von VMs ändert, ist es dem Client egal. Es sind keine Befehlsendpunkte zum Aktualisieren vorhanden. Wenn Sie in RPC den API-Endpunkt von shutdownin ändern , haben shut-downSie alle Ihre Clients beschädigt, da sie jetzt den Befehl zum Aufrufen auf dem Server nicht kennen.

REST ähnelt der deklarativen Programmierung, bei der Sie anstelle einer Liste mit Anweisungen zur Änderung lediglich angeben, wie Sie dies wünschen, und die Programmierumgebung dies herausfinden lassen.

Cormac Mulhall
quelle
Danke für deine Antwort. Der zweite Teil über die Entkopplung von Client und Server entspricht weitgehend meinem Verständnis. Haben Sie eine Ressource / einen Link, der den ersten Teil Ihrer Antwort sichert? Welche REST-Einschränkung ist genau verletzt, wenn ich Ressourcen, HTTP-Methoden, Hypermedien, selbstbeschreibende Nachrichten usw. verwende?
Leifbattermann
Es gibt kein Problem mit der Verwendung von Ressourcen, HTTP-Methoden usw. Immerhin ist HTTP ein REST-Protokoll. Wo ein Problem auftritt, wird das verwendet, was Sie als "Aktionsendpunkte" bezeichnen. In REST gibt es Ressourcen, die Konzepte oder Dinge darstellen (z. B. die virtuelle Maschine 42 oder mein Bankkonto), und die HTTP-Verben übertragen den Status dieser Ressourcen zwischen Clients und Servern. Das ist es. Was Sie nicht tun sollten, ist zu versuchen, neue Befehle zu erstellen, indem Sie Nicht-Ressourcen-Endpunkte mit HTTP-Verben kombinieren. 'Virtualmachines / 42 / actions' ist also keine Ressource und sollte in einem RESTful-System nicht vorhanden sein.
Cormac Mulhall
Oder anders ausgedrückt, der Client sollte nicht versuchen, Befehle auf dem Server auszuführen (abgesehen von den begrenzten HTTP-Verben, die sich ausschließlich mit der Zustandsübertragung von Ressourcen befassen). Der Client sollte seine Kopie der Ressource aktualisieren und dann einfach den Server auffordern, diesen neuen Status zu akzeptieren. Die Akzeptanz dieses neuen Zustands kann Nebenwirkungen haben (die VM 42 ist physisch heruntergefahren), die jedoch für den Kunden unerheblich sind. Wenn der Client nicht versucht, Befehle auf dem Server auszuführen, besteht keine Kopplung über diese Befehle zwischen dem Client und dem Server.
Cormac Mulhall
Sie können den Befehl für die Ressource ausführen ... Wie würden Sie sagen, "einzahlen" und "auszahlen" auf ein Bankkonto? Es würde CRUD für etwas verwenden, das nicht CRUD ist.
Konrad
Es ist besser zu verwenden, POST /api/virtualmachines/42/shutdownanstatt irgendwelche "Nebenwirkungen" zu haben. Die API muss für den Benutzer verständlich sein. Woher weiß ich, dass beispielsweise DELETE /api/virtualmachines/42die VM heruntergefahren wird? Ein Nebeneffekt für mich ist ein Fehler. Wir sollten unsere APIs so gestalten, dass sie verständlich und selbsterklärend sind
Konrad