Ich habe viele Diskussionen hier auf SO gelesen, habe Jon Moores Präsentation gesehen (welche erklärte viel, btw) und lese Roy Fieldings Blog-Post auf HATEOAS, aber ich fühle mich immer noch ein wenig im Dunkeln, wenn es um Client-Design geht.
API-Frage
Im Moment gebe ich einfach xhtml mit forms / anchors und Definitionslisten zurück, um die Ressourcen darzustellen. Der folgende Ausschnitt zeigt, wie ich Formulare / Anker / Listen auslege.
%Vor%Meine Frage bezieht sich hauptsächlich auf Formulare. In Jon's Talk dokumentiert er Formulartypen wie (add_location_form) etc. und die benötigten Eingaben für sie. Ich habe nicht viele Ressourcen, aber ich dachte an abstrakte Formulartypen (hinzufügen, löschen, aktualisieren usw.) und notieren Sie in der Dokumentation, dass Sie für (hinzufügen, aktualisieren) eine gültige Darstellung der Zielressource senden müssen und mit löschen, dass Sie die Kennung senden müssen.
Frage 1: Sollten wir den Begriff "HATEOAS" nicht wirklich dazu benutzen, den Client dazu zu bringen, das Formular "zu entdecken" (indem man sie hinzufügt, löscht, aktualisiert usw.) ) und senden Sie einfach alle Daten zurück, die wir ihnen gegeben haben? Meine eigentliche Frage hier (nicht zur Diskussion) ist, ob dies der guten Praxis entspricht?
Kundenfrage
Nach HATEOAS, wie unsere Aktionen auf Ressourcen entdeckbar sind, wie wirkt sich das auf Client-Code (Konsumenten der API) und deren Benutzer aus? Es klingt großartig, dass die UI nach diesen Prinzipien nur verfügbare Aktionen anzeigen sollte, aber wie ist das implementiert?
Mein aktueller Ansatz analysiert die Antwort als xml und usin xpath, um nach den Aktionen zu suchen, die zum Zeitpunkt der Client-Entwicklung bekannt sind (dokumentierte Formularklassen, z. B. hinzufügen, löschen, aktualisieren) und die ui-Steuerelemente anzeigen, sofern sie verfügbar sind .
Frage 2: Bin ich falsch in meiner Art zu entdecken? Oder ist das zu viel Magie für den Kunden (die Formklassen zu kennen)? Würde dies nicht davon ausgehen, dass der Client weiß, welche Aktionen für jede Ressource verfügbar sind (was in Ordnung sein kann, weil es ein Grund für die Erstellung des Clients ist, oder?) Und sollte die Zuordnung von Aktionen (Formularklassen) zu Ressourcen dokumentiert werden oder dokumentieren Sie einfach die Formularklassen und erlauben dem Client (und dem Client-Entwickler), sie zu recherchieren und zu entdecken?
Ich weiß, dass ich überall dabei bin, aber jede Einsicht wird sehr geschätzt. Ich markiere eine Antwort, die eine dieser beiden Fragen gut beantwortet. Danke!
Nein, du bist ziemlich genau richtig.
Browser rendern einfach die HTML-Nutzdaten und verlassen sich darauf, dass der Mensch die Formulare tatsächlich interpretiert, eine Bedeutung findet und möglicherweise die Formulare entsprechend füllt.
Maschinenkunden tendieren im "interpretieren" -Teil dazu, ziemlich schlecht zu sein. Stattdessen müssen die Entwickler die Entscheidungen im Voraus treffen und den Maschinenclient in qualvollen Details führen.
Im Idealfall würde ein "intelligenter" HATEOS-Client bestimmte Fakten haben und sich des Kontexts bewusst sein, damit er diese Fakten den Anforderungen des Dienstes besser zuordnen kann.
Weil wir das machen, richtig? Wir sehen ein Formular "Oh, sie wollen Name, Adresse, Kreditkartennummer". Wir wissen nicht nur, was "Name", "Adresse" und "Kreditkartennummer" bedeuten, wir können auch erkennen, dass sie meinen Namen oder den Namen der Person auf der Kreditkarte oder den Namen der Person, die versendet wird, meinen zu.
Maschinen versagen auch im "intuitiven" Teil ziemlich gut. Als Entwickler können Sie also in der Logik dessen codieren, was Sie für notwendig halten, um die richtigen Fakten und ihre Platzierung zu bestimmen.
Aber zurück zum idealen Client würde es jedes Formular sehen, "wissen", was die Felder wollten, seine interne Liste von "Fakten" konsultieren, und dann die Nutzdaten für die Anfrage richtig ausfüllen und schließlich die Anfrage stellen / p>
Sie können sehen, dass eine triviale und offensichtlich spröde Methode darin besteht, die Parameternamen einfach den internen Daten zuzuordnen. Wenn der Parametername "name" lautet, können Sie das beispielsweise so programmieren: firstName + "" + lastName. Oder Sie betrachten das tatsächliche rel "wissen", dass sie über den Versand sprechen, und verwenden Sie: shipTo.firstName + "" + shipTo.lastName.
Im Laufe der Zeit könnten Sie im Idealfall eine Sammlung von Mappings erstellen, so dass, wenn plötzlich eine Nutzlast ein neues Feld einführte und es sich dabei um ein Feld handelt, das Sie bereits kennen, Sie es auch "automatisch" ausfüllen könnten. ohne Änderung für den Kunden.
Aber die einfache Wahrheit ist, dass, während dies getan werden kann, es so ziemlich nicht getan ist. Die Semantik ist meist zu vage, man müsste sowieso jedes Mal neue Intuition für jede neue Payload programmieren, also kann man auch direkt in die Payload eincoden und damit fertig werden.
Die Hauptsache ist jedoch, besonders bei HATEOS, dass Sie Ihre Daten nicht auf den Server "zwingen". Der Server sagt dir, was er will, besonders wenn er dir Formulare gibt.
Der Denkprozess ist also nicht "Oh, wenn ich eine Versandrechnung haben möchte, sehe ich, dass sie jetzt Name, Adresse und Bestellnummer haben wollen, und sie wollen, dass sie url codiert ist, und sie wollen, dass sie an Ссылка , also sende ich einfach immer: name + "& amp;" + adresse + "& amp;" + orderNummer jedes mal an Ссылка . Einfach! ".
Was Sie tun möchten, ist "Ich sehe, dass sie einen Namen, eine Adresse und eine Bestellnummer haben wollen. Also werde ich für jede Anfrage ihr Formular lesen. Ich werde jedes Mal prüfen, welche Felder sie haben wollen Wenn sie einen Namen haben wollen, gebe ich ihnen einen Namen, wenn sie eine Adresse haben wollen, gebe ich ihnen eine Adresse, wenn sie eine Bestellnummer haben wollen, gebe ich ihnen die Bestellnummer und wenn sie PRE-POPULATED Felder haben (oder sogar "versteckt") "Felder"), werde ich auch diese zurückschicken, und ich werde es in der Kodierung senden, die sie verlangten, vorausgesetzt, ich unterstütze es, zu der URL, die ich aus dem Aktionsfeld des FORM-Tags erhielt. ".
Sie können im ersten Fall sehen, dass Sie ANNEHMEN, dass sie diese Nutzlast jedes Mal wollen. Genau wie wenn Sie URLs hart codieren würden. Während sie mit der zweiten vielleicht beschlossen haben, dass Name und Adresse überflüssig sind, fragen sie nicht mehr danach. Vielleicht haben sie einige nette Standardeinstellungen für neue Funktionen hinzugefügt, die du vielleicht noch nicht unterstützt. Vielleicht haben sie die Codierung auf mehrere Teile geändert? Oder die Endpunkt-URL geändert. Wer weiß.
Sie können nur senden, was Sie wissen, wenn Sie den Client codieren, richtig? Wenn sie Dinge ändern, können Sie nur tun, was Sie tun können. Wenn sie Felder hinzufügen, fügen sie hoffentlich Felder hinzu, die nicht benötigt werden. Aber wenn sie die Schnittstelle brechen, hey, brechen sie die Schnittstelle und Sie erhalten einen Fehler zu protokollieren. Nicht viel kann man dort machen.
Aber je mehr Sie HATEOS nutzen, desto mehr davon stellen Sie für Sie bereit, damit Sie flexibler sein können: Auszufüllende Formulare, richtiges Weiterleiten von Weiterleitungen, Beachtung von Kodierungs- und Medientypen, desto flexibler ist Ihr Client wird.
Am Ende machen es die meisten Leute einfach nicht in ihren Kunden. Sie programmieren hart, weil es einfach ist, und sie gehen davon aus, dass sich das Backend nicht schnell genug ändert, um von Bedeutung zu sein, oder dass Ausfallzeiten, wenn solche Änderungen eintreten, akzeptabel sind, bis sie den Client korrigieren. Typischer Weise, insbesondere bei internen Systemen, erhalten Sie einfach eine E-Mail von den Entwicklern, "die die XYZ-API geändert haben und am 1. März live gehen. Bitte aktualisieren Sie Ihre Kunden und koordinieren Sie das Integrationsteam beim Integrationstest. Kthx".
Das ist nur die Realität. Das bedeutet nicht, dass Sie es nicht tun sollten oder dass Sie Ihre Server nicht intelligenter für klügere Clients machen sollten. Erinnern Sie sich an einen fehlerhaften Client, der davon ausgeht, dass kein gutes REST-basiertes System ungültig ist. Diese Systeme funktionieren gut mit schrecklichen Kunden. wget ftw, was?
Tags und Links rest hateoas api-design