Beim Vergleich der REST [api] -Struktur mit einem OO-Modell sehe ich folgende Ähnlichkeiten:
Beide:
Sind datenorientiert
- REST = Ressourcen
- OO = Objekte
Surround-Betrieb um Daten
- REST = Surround-VERBS (Get, Post, ...) um Ressourcen herum
- OO = Förderung des Betriebs um Objekte durch Kapselung
Gute OO-Praktiken stehen jedoch nicht immer auf REST-APIs, wenn Sie beispielsweise versuchen, das Fassadenmuster anzuwenden: In REST verfügen Sie nicht über einen Controller, der alle Anforderungen verarbeitet, UND Sie verbergen die Komplexität interner Objekte nicht.
Im Gegenteil, REST fördert die Veröffentlichung von Ressourcen aller Beziehungen zu einer Ressource und anderen in mindestens zwei Formen:
über Ressourcenhierarchiebeziehungen (Ein Kontakt mit der ID 43 besteht aus einer Adresse 453):
/api/contacts/43/addresses/453
über Links in einer REST-JSON-Antwort:
>> GET /api/contacts/43 << HTTP Response { id: 43, ... addresses: [{ id: 453, ... }], links: [{ favoriteAddress: { id: 453 } }] }
Zurück zu OO: Das Fassadenentwurfsmuster berücksichtigt a Low Coupling
zwischen einem ObjektA und seinem ' ObjektB-Client ' sowie High Cohesion
für dieses ObjektA und seine interne Objektzusammensetzung ( ObjektC , ObjektD ). Mit dem Objecta Schnittstelle, erlauben diese einen Entwickler zu begrenzen Auswirkungen auf ObjectB der Objecta internen Veränderungen (in ObjectC und ObjectD ), solange die Objecta api (Operationen) sind nach wie vor eingehalten werden .
In REST werden die Daten (Ressource), die Beziehungen (Links) und das Verhalten (Verben) in verschiedenen Elementen aufgelöst und stehen dem Web zur Verfügung.
Wenn ich mit REST spiele, habe ich immer Auswirkungen auf Codeänderungen zwischen meinem Client und meinem Server: Weil ich High Coupling
zwischen meinen Backbone.js
Anforderungen und Low Cohesion
zwischen Ressourcen habe.
Ich habe nie herausgefunden, wie ich mich Backbone.js javascript application
mit der Erkennung von " REST-Ressourcen und -Funktionen " befassen kann , die durch REST-Links gefördert wird. Ich verstehe, dass das WWW von mehreren Servern bedient werden soll und dass die OO-Elemente explodiert werden mussten, um von vielen Hosts dort bedient zu werden, aber für ein einfaches Szenario wie das "Speichern" einer Seite, die einen Kontakt mit ihren Adressen zeigt, Am Ende habe ich:
GET /api/contacts/43?embed=(addresses) [save button pressed] PUT /api/contacts/43 PUT /api/contacts/43/addresses/453
Dies führte dazu, dass ich die atomare Transaktionsverantwortung für die Speicheraktion auf die Browseranwendungen verlagerte (da zwei Ressourcen separat angesprochen werden können).
In diesem Sinne, wenn ich meine Entwicklung nicht vereinfachen kann (Fassadenentwurfsmuster nicht anwendbar) und wenn ich meinem Kunden mehr Komplexität (Umgang mit atomarer Transaktionsspeicherung) bringe, wo ist der Vorteil von RESTful?
quelle
PUT /api/contacts/43
wenn die Aktualisierungen innerer Objekte kaskadiert werden? Ich hatte viele APIs wie diese entworfen (Master-URL liest / erstellt / aktualisiert das "Ganze" und Sub-URLs aktualisieren die Teile). Stellen Sie einfach sicher, dass Sie die Adresse nicht aktualisieren, wenn keine Änderungen erforderlich sind (aus Leistungsgründen).Antworten:
Ich denke, Objekte basieren nur korrekt auf kohärenten Verhaltensweisen und nicht auf Daten. Ich werde provozieren und sagen, dass Daten in der objektorientierten Welt fast irrelevant sind. Tatsächlich ist es möglich und manchmal üblich, Objekte zu haben, die niemals Daten zurückgeben, z. B. "Protokollsenken", oder Objekte, die niemals die Daten zurückgeben, an die sie übergeben werden, beispielsweise wenn sie statistische Eigenschaften berechnen.
Lassen Sie uns die PODS (die kaum mehr als Strukturen sind) und die realen Objekte, die Verhaltensweisen aufweisen (wie die
Contacts
Klasse in Ihrem Beispiel) , nicht verwechseln 1 .PODS sind im Grunde genommen eine Annehmlichkeit, um mit Repositorys und Geschäftsobjekten zu kommunizieren. Sie ermöglichen, dass der Code typsicher ist. Nicht mehr und nicht weniger. Geschäftsobjekte hingegen bieten konkrete Verhaltensweisen wie die Validierung oder Speicherung Ihrer Daten oder die Verwendung zur Berechnung.
Wir verwenden also Verhaltensweisen, um die "Kohäsion" 2 zu messen , und es ist leicht zu erkennen, dass in Ihrem Objektbeispiel eine gewisse Kohäsion besteht, obwohl Sie nur Methoden zum Bearbeiten von Kontakten der obersten Ebene und keine Methoden zum Bearbeiten von Adressen anzeigen.
In Bezug auf REST können Sie REST-Services als Datenrepositorys anzeigen. Der große Unterschied zum objektorientierten Design besteht darin, dass es (fast) nur eine Designauswahl gibt: Sie haben vier grundlegende Methoden (mehr, wenn Sie
HEAD
zum Beispiel zählen) und natürlich haben Sie viel Spielraum mit den URIs, sodass Sie geschickt arbeiten können Sachen wie viele IDs weitergeben und eine größere Struktur zurückbekommen. Verwechseln Sie die übergebenen Daten nicht mit den von ihnen ausgeführten Vorgängen . Bei Kohäsion und Kopplung geht es um Code und nicht um Daten .Es ist klar, dass REST-Services eine hohe Kohäsion (jede Art der Interaktion mit einer Ressource befindet sich am selben Ort) und eine geringe Kopplung aufweisen (jedes Ressourcen-Repository erfordert keine Kenntnis der anderen).
Die grundlegende Tatsache bleibt jedoch, dass REST im Wesentlichen ein einzelnes Repository-Muster für Ihre Daten ist. Dies hat Konsequenzen, da es sich um ein Paradigma handelt, das auf einer einfachen Zugänglichkeit über ein langsames Medium basiert, bei dem hohe Kosten für "Chattiness" anfallen: Clients möchten normalerweise so wenig Vorgänge wie möglich ausführen, erhalten aber gleichzeitig nur die Daten, die sie benötigen . Dies bestimmt, wie tief ein Datenbaum ist, den Sie zurücksenden möchten.
Bei (korrektem) objektorientiertem Design führt jede nicht triviale Anwendung viel komplexere Operationen aus, beispielsweise durch Komposition. Sie könnten Methoden haben, um spezialisiertere Operationen mit den Daten durchzuführen - was auch so sein muss, denn während REST ein API-Protokoll ist, wird OOD verwendet, um ganze Anwendungen für Benutzer zu erstellen! Aus diesem Grund ist die Messung von Kohäsion und Kopplung bei OOD von grundlegender Bedeutung, bei REST jedoch nahezu unbedeutend.
Inzwischen sollte klar sein, dass die Analyse des Datenentwurfs mit OO-Konzepten keine zuverlässige Methode zur Messung ist: Es ist wie der Vergleich von Äpfeln und Orangen!
Tatsächlich stellt sich heraus, dass die Vorteile von RESTful (meistens) die oben beschriebenen sind: Es ist ein gutes Muster für einfache APIs über ein langsames Medium. Es ist sehr zwischenspeicherbar und zerbrechbar. Es hat eine feinkörnige Kontrolle über das Geschwätz usw.
Ich hoffe das beantwortet deine (ziemlich facettenreiche) Frage :-)
1 Dieses Problem ist Teil einer größeren Reihe von Problemen, die als objektrelationale Impedanzfehlanpassung bekannt sind . Befürworter von ORMs sind im Allgemeinen in dem Lager, das die Ähnlichkeiten zwischen Datenanalyse und Verhaltensanalyse untersucht, aber ORMs wurden in letzter Zeit kritisiert, weil sie die Impedanzfehlanpassung nicht wirklich zu beheben scheinen und als undichte Abstraktionen gelten .
2 http://en.wikipedia.org/wiki/Cohesion_(computer_science)
quelle
Die Antwort auf "Wo ist der Vorteil von RESTful?" wird hier gründlich analysiert und erklärt: http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm
Die Verwirrung in dieser Frage ist jedoch, dass es nicht um Merkmale von REST und wie man damit umgeht, sondern um die Annahme, dass das Design der URLs, die Sie für Ihr Beispielsystem erstellt haben, etwas mit RESTful zu tun hat. Schließlich gibt REST an, dass es Dinge gibt, die als Ressourcen bezeichnet werden, und dass eine Kennung für diejenigen bereitgestellt werden sollte, auf die verwiesen werden muss. Dies schreibt jedoch nicht vor, dass beispielsweise Entitäten in Ihrem ER-Modell eine 1-1-Entsprechung mit den von Ihnen erstellten URLs haben sollten (Weder dass die URLs die Kardinalität der ER-Beziehungen im Modell codieren sollten).
Bei Kontakten und Adressen könnten Sie eine Ressource definiert haben, die diese Informationen gemeinsam als eine Einheit darstellt, obwohl Sie diese Informationen möglicherweise extrahieren und in beispielsweise verschiedenen relationalen DB-Tabellen speichern möchten, wenn sie PUT oder POST sind .
quelle
Das ist, weil Fassaden ein "Kludge" sind; Sie sollten sich 'API-Abstraktion' und 'API-Verkettung' ansehen. Die API ist eine Kombination aus zwei Funktionssätzen: E / A und Ressourcenverwaltung. Lokal ist die E / A in Ordnung, aber innerhalb einer verteilten Architektur (z. B. Proxy, API-Gate, Nachrichtenwarteschlange usw.) wird die E / A gemeinsam genutzt, und somit werden die Daten und Funktionen dupliziert und verwickelt. Dies führt zu architektonischen Querschnittsproblemen. Dies plagt ALLE existierenden Apis.
Die einzige Möglichkeit, dies zu beheben, besteht darin, die E / A-Funktionalität für die API auf einen Pre / Post-Handler (wie einen handlerIntercepter in Spring / Grails oder einen Filter in Rails) zu abstrahieren, damit die Funktionalität als Monade verwendet und von Instanzen und externen Benutzern gemeinsam genutzt werden kann Werkzeuge. Daten für die Anforderung / Antwort müssen auch in einem Objekt externalisiert werden, damit sie auch gemeinsam genutzt und neu geladen werden können.
http://www.slideshare.net/bobdobbes/api-abstraction-api-chaining
quelle
Wenn Sie Ihren REST-Service oder allgemein jede Art von API als zusätzliche Schnittstelle verstehen , die Clients zur Verfügung steht, damit diese Ihre Controller darüber programmieren können, wird es plötzlich einfach. Der Service ist nichts weiter als eine zusätzliche Ebene über Ihrer Geschäftslogik.
Mit anderen Worten, Sie müssen die Geschäftslogik nicht wie in Ihrem Bild oben auf mehrere Controller aufteilen, und was noch wichtiger ist, Sie sollten es nicht tun. Die Datenstrukturen, die zum Datenaustausch verwendet werden, müssen nicht mit den Datenstrukturen übereinstimmen, die Sie intern verwenden. Sie können sehr unterschiedlich sein.
Es ist Stand der Technik und allgemein anerkannt, dass es eine schlechte Idee ist, eine Geschäftslogik in den UI-Code zu integrieren. Aber jede Benutzeroberfläche ist nur eine Art Schnittstelle (das I in der Benutzeroberfläche), um die dahinter stehende Geschäftslogik zu steuern. Folglich scheint es offensichtlich, dass es auch eine schlechte Idee ist, eine Geschäftslogik in die REST-Serviceschicht oder eine andere API-Schicht zu integrieren.
Konzeptionell gibt es keinen so großen Unterschied zwischen Benutzeroberfläche und Service-API.
quelle