Wir implementieren einen Request / Response-Service-Layer mit WCF, wo jeder Request erbt von einer Base Request-Klasse und jede Antwort erbt von der Basis-Response-Klasse.
Der Dienst verfügt über eine einzige Prozessmethode, die eine Anforderung akzeptiert und eine Antwort zurückgibt.
%Vor%Bestimmte Mitglieder unseres Teams sind jedoch der Meinung, dass statt des Vorgangsvertrags, der eine einzelne Anfrage / Antwort erwartet und zurückgibt, eine Reihe von Anfragen / Antworten akzeptiert und zurückgegeben werden sollte.
%Vor%Ich persönlich finde es nicht semantisch korrekt und in Fällen, in denen eine Sammlung verwandter Anforderungen sofort (vielleicht in einem Batch) verarbeitet werden muss, würde ich die Einführung von BatchRequest und BatchResponse-Nachrichten in Betracht ziehen.
%Vor%Das Annehmen und Zurückgeben eines Arrays scheint mir nicht korrekt zu sein, und das ist sicherlich ein Muster, das ich nirgendwo sonst gesehen habe. Ist da etwas mehr falsch? Wenn ja, was ist das?
Einige Leute glauben, dass das Akzeptieren / Zurückgeben von Arrays es uns erlauben würde, die zusätzliche Komplexität der Einführung von Batch-Anfragen (wie die oben dargestellte) nicht zu haben, und dass Sie trotzdem eine einzige Anfrage im Array senden könnten.
Danke
Zunächst fügen Arrays unnötige Komplexität hinzu. Halten Sie es einfach (und) dumm.
Zum Beispiel. Wie sollten Fehler behandelt werden? Wenn die Anfrage # 1 fehlschlägt, sollten die Anfragen # 2 und # 3 trotzdem ausgeführt werden? Wie sollten die Fehler gemeldet werden?
Welche Probleme möchten Ihre Kollegen lösen, indem Sie alle Anfragen-Arrays erstellen? Wenn es Leistung ist, riecht es wie vorzeitige Optimierung. Es gibt mehrere andere Möglichkeiten, die Leistung zu verbessern, aber tun Sie nichts, bis es wirklich notwendig ist.
Wenn Sie den Client freigeben möchten, anstatt auf das Ergebnis zu warten, wechseln Sie zu einem asynchronen Client.
Ich würde eine einzelne Anfrage und Antwort bevorzugen und das Befehlsmuster für die Stapelverarbeitung mehrerer Aktionen verwenden.
Ich finde, SOA ist kompliziert genug, ohne dass unerwartete Muster auftauchen. Was passiert, wenn ein Teil der Anfragen fehlschlägt, werden alle zurückgenommen oder nur die fehlgeschlagenen? Aaarghhh, mein Kopf fängt an zu schmerzen.
IMO, Ihre Entscheidung, diese Dienste zu entwerfen / zu modellieren, sollte vollständig auf ihren Nutzungsszenarien beruhen.
Während der SOA-Modellierung sollte das Ziel darin bestehen, lose gekoppelte Systeme / Dienste zu erstellen, die die betreffende Geschäftsdomäne (Anwendungen) unterstützen.
Idealerweise sollte Ihr Service nicht zu granular oder zu komplex sein. Seine Wiederverwendung ist ebenso wichtig. Aus diesem Grund - müssen Sie überlegen, was die Kunden brauchen.
Hier sind ein paar Szenarien, in denen jemand nützlich sein könnte
Information as a Service
Zugriff auf Daten (Stammdaten) über gemeinsame Dienste. - In diesem Fall wäre es wirklich nicht sinnvoll, im Batch-Modus auf die Stammdaten zuzugreifen.
Aktualisierung von Gruppendaten - Ein Dienst zum Migrieren von Benutzern zum neuen Verkaufsplan (!)
Und ich denke nicht, dass die Behandlung von Fehlerszenarien mit Arrays ein Problem ist - Sie können das Problem wirklich nicht verallgemeinern - es ist sehr kontextabhängig. Es ist eine Designentscheidung.
Wie im Fall [2] oben - könnten Sie alles verarbeiten und Fehlercodes innerhalb der Antwort [] zurückgeben.
Als Konzept scheint eine Batch-Anfrage sinnvoll zu sein - ich habe solche Muster für bestimmte Dienstleistungen in der Vergangenheit eingeführt, um "Chatteriness" zu reduzieren. Es scheint zwei Response-Konzepte zu geben: Habe ich den Batch als Ganzes verstanden und was ist die Antwort für jedes Mitglied des Batchs? Daher ist es ein bisschen mehr als nur ein einfaches Array von Antworten.
Ich würde auch die Möglichkeit einer verzögerten Ausführung von Batch-Mitgliedern in Erwägung ziehen. Daher lautet die erste Antwort "Ich habe Ihren Batch verstanden" mit einigen anderen Diensten, um den Status einzelner Batch-Mitglieder oder einen Mechanismus für die asynchrone Antwortbereitstellung zu erhalten.
Zusammenfassung: Sie benötigen individuelle Anfrage / Antwort, eine Batch-Funktion ist wahrscheinlich nützlich und ist offen für einen gewissen Grad der Erweiterung.
Personen, die stapelweise Anfragen vorschlagen, denken immer über die Schnittstellenleistung nach. Und das ist eine gute Sache. Die Frage sollte nicht lauten: "Sollen wir Anfragen bündeln oder nicht?", Sondern "Können wir eine akzeptable Leistung über die Schnittstelle erreichen?". Ich habe mit Schnittstellen gearbeitet, die gut auf LANs ( z. B. , 10Mb Ethernet innerhalb von Büros) funktionierten, die aber über transatlantische Verbindungen langsam waren und einfach über transpazifische Verbindungen fehlschlugen. Das Beispiel, das ich im Sinn hatte, behandelte die Schnittstelle eher als eine RPC-Schicht als eine "Business-Operation" -Schicht, und es zeigte sich in den Netzwerkspuren.
jgaffin macht den Nagel deutlich auf den Kopf - was bedeutet der Ausfall einer einzelnen Anfrage für die Charge? Sind die Operationen eine geordnete Liste, so dass die nachfolgenden Operationen nicht versucht werden müssen? Sind sie nur ein Set, zur Übertragung gruppiert und ansonsten nicht verwandt? Sind sie eine zusammengesetzte Transaktion, so dass vorherige erfolgreiche Vorgänge zurückgesetzt werden sollten?
API-Konstruktion ist eine Kunst, keine Wissenschaft und vielleicht sogar eine schwarze Kunst. Um Gerechtigkeit Potter Stewart zu paraphrasieren,
"Ich werde heute nicht weiter versuchen Definieren Sie die Arten von Material I zu verstehen, in [gut API-Design]; und vielleicht könnte ich nie gelingt es, dies verständlich zu tun. Aber Ich weiß es, wenn ich es sehe. "
Was Sie in Betracht ziehen, ist das, was ich Stratifikation nenne - die Implementierung eines einfachen Protokolls über ein komplexes Protokoll hinaus . Es ist völlig und völlig fehlgeleitet. Request / Response, wie du denkst, ist bereits da draußen und es heißt HTTP.
Auch wenn Sie keine REST-Dienste verwenden möchten, sollten Sie dies nicht tun. Wenn Sie Probleme beim Aufrufen von Diensten aufgrund der Aktualisierung ihrer Verträge haben, tun Sie etwas falsch. Eine Lösung, wenn Sie gezwungen sind, WCF anstelle von etwas Besserem wie nServiceBus oder MassTransit oder einem anderen ESB-Framework zu verwenden, könnte folgendermaßen aussehen:
Nach meiner Erfahrung ist Ihr Ansatz, mit einem einzelnen Anfrage / Antwort-Muster zu beginnen und später ein separates BatchRequest / BatchResponse-Muster (welches Arrays von Anfragen / Antworten aufweist) zu veröffentlichen, der beste Ansatz sowohl kurz- als auch langfristig für deine API.
Das anfängliche API-Muster, das verfügbar gemacht wird, sollte eine einzige Anfrage und Antwort sein, nur um eine einfach zu verstehende Oberfläche zu haben. Eine einfache Schnittstelle macht die Muster der API (ihre Methoden und Objekte) einfach zu erlernen, was für die Benutzerakzeptanz wichtig ist. Ihre Benutzer werden die Einfachheit zu schätzen wissen, wenn sie zuerst die API erlernen und versuchen, den Dienst einfach einzurichten. Das Erzwingen von Benutzern, Anfragenanordnungen in der ursprünglichen API zu erstellen, wird nicht geschätzt, und die API wird komplizierter. Dies ist eine vorzeitige Optimierung für Ihre Kollegen.
Ihre Kollegen haben jedoch Recht, dass Ihre Benutzer schließlich die Option für Batchanforderungen und Antworten wünschen, wenn sie mit der API vertrauter werden. Ihre Kollegen Anliegen sind am besten gedient, indem Sie ein separates BatchRequest / BatchResponse-Muster implementieren, wie Sie vorgeschlagen. Es ist üblich, ein separates BatchRequest / BatchResponse-Muster zu implementieren. Dies kann so erfolgen, dass ein Großteil des Codes in der Implementierung des Singleton-Request / Response-Patterns wieder verwendet wird. Um es klar zu sagen, die Idee besteht darin, dass Sie Ihre Singleton-Anfragen früher absetzen. Die Idee, dass Ihre API mit einem Anforderungs- / Antwort-Array-Muster beginnen muss und in unnötiger und unbegründeter Weise an ein Anforderungs- / Antwort-Array-Muster gebunden sein muss, ist meiner Erfahrung nach.
Jetzt, da ich nicht weiß, was die Anwendungsfälle Ihres Kollegen sind, werde ich eine Vermutung darüber machen, warum sie die Arrays von Anfang an wollen. Wenn Ihre Kollegen Anfragenanordnungen haben möchten, weil sie Bedenken haben, mehrere CRUD-Vorgänge für mehrere Objekte auszuführen, besteht die Lösung nicht darin, Anfragenanordnungen zu erstellen, sondern einzelne Anfragen an einen einzelnen CRUD-Vorgangstyp zu binden und die Anforderung übernehmen zu lassen ein Array von Objekten, an denen die Operation ausgeführt werden soll. Sie möchten Benutzer nicht dazu zwingen, für jedes Objekt eine individuelle Anfrage auszuführen, da dies nicht skalierbar ist. Batching wird am besten als eine erweiterte API-Technik betrachtet, die nur verwendet wird, wenn die grundlegenden Muster der API verstanden werden und wenn Ihre Benutzer ihre Apps erweitern möchten.
Lassen Sie zuerst ein einzelnes Anfrage / Antwort-Muster und dann ein optionales Batch-Anfrage / Batch-Antwort-Muster offen legen. Erstellen Sie das einzelne Request / Response-Pattern mit dem Gedanken, dass diese Requests eventuell zusammengeführt werden.
Tags und Links wcf architecture web-services soa