Erkennbarkeit der RESTful-API-Laufzeit / HATEOAS-Client-Design

79

Für ein SaaS-Startup, an dem ich beteiligt bin, erstelle ich sowohl eine RESTful-Web-API als auch einige Client-Apps auf verschiedenen Plattformen, die diese verwenden. Ich glaube, ich habe die API herausgefunden, aber jetzt wende ich mich an die Kunden. Während ich über REST gelesen habe, sehe ich, dass ein wesentlicher Teil von REST die Entdeckung ist , aber es scheint eine große Debatte zwischen zwei verschiedenen Interpretationen dessen zu geben, was Entdeckung wirklich bedeutet:

  1. Entwicklererkennung : Der Entwickler codiert zahlreiche API-Details fest in den Client, z. B. Ressourcen-URIs, Abfrageparameter, unterstützte HTTP-Methoden und andere Details, die er durch Durchsuchen der Dokumente und Experimentieren mit den Antworten der API ermittelt hat. Diese Art der Erkennung erfordert meiner Meinung nach eine coole Verknüpfung und die Frage nach der API-Versionierung und führt zu einer harten Kopplung des Client-Codes an die API. Nicht viel besser, als wenn man eine gut dokumentierte Sammlung von RPCs verwendet.

  2. Laufzeiterkennung - Die Client-App selbst kann mit wenigen oder keinen Out-of-Band-Informationen alles herausfinden, was sie benötigt (vermutlich nur Kenntnisse über die Medientypen, mit denen sich die API befasst). Links können heiß sein. Um die API jedoch sehr effizient zu gestalten, scheint eine Menge Link-Template für Abfrageparameter erforderlich zu sein, wodurch sich Out-of-Band-Informationen wieder einschleichen. Es gibt möglicherweise andere Schwierigkeiten, an die ich noch nicht gedacht habe, da ich es nicht getan habe zu diesem Punkt in der Entwicklung gekommen. Aber ich mag die Idee der losen Kopplung.

Die Entdeckung der Laufzeit scheint der heilige Gral von REST zu sein, aber ich sehe kaum eine Diskussion darüber, wie ein solcher Client implementiert werden kann. Fast alle REST-Quellen, die ich gefunden habe, scheinen von einer Entwicklerentdeckung auszugehen. Kennt jemand einige Runtime Discovery-Ressourcen? Empfohlene Vorgehensweise? Beispiele oder Bibliotheken mit echtem Code? Ich arbeite in PHP (Zend Framework) für einen Client. Objective-C (iOS) für den anderen.

Ist die Runtime-Entdeckung angesichts der derzeitigen Tools und Kenntnisse in der Entwicklergemeinde ein realistisches Ziel? Ich kann meinem Client schreiben, dass er alle URIs undurchsichtig behandelt, aber wie dies am effizientesten funktioniert, ist eine Frage, insbesondere bei Verbindungen mit geringer Bandbreite. Wie auch immer, URIs sind nur ein Teil der Gleichung. Was ist mit Link-Templating im Runtime-Kontext? Wie wäre es mit der Kommunikation, welche Methoden unterstützt werden, abgesehen von vielen OPTIONS-Anfragen?

curtisdf
quelle
2
Nur eine kleine Seite Ihrer OPTIONS-Referenz. Sie können den Header 'Allow' verwenden, um zulässige Ressourcenoperationen außerhalb einer OPTIONS-Anforderung zu kommunizieren. Roy Fielding geht so weit, den Header als eine Form von Hypertext zu betrachten - siehe hier .
Paulkmoore
Wenn es sich um eine gr8-Frage handelt, erhalten die Hauptprobleme die Liste der anwendbaren Methoden. Sollte der Client in der Lage sein, URLs für die reguläre CRUD-Operation zu erstellen, oder wird dies als "Out-of-Band" bezeichnet? Sagen wir, wenn wir auch Links für CRUD-Operationen bereitstellen, wie machen Sie "Formulare" in json? Wenn Sie anwendungsspezifische Medientypen verwenden und keine "Formulare" erstellen müssen, Wat jedoch die Standardmethode zum Erkennen von Medientypen (z. B. JSON-Schema) ist, wird der Prozess zum Erkennen des Schemas als nicht "out-of-" betrachtet. Band "für Kunden?
Redzedi
xhtml sieht so gut und flüssig aus, aber wenn du json machen musst, dann ist es wohl ziemlich amorph
redzedi

Antworten:

19

Dies ist definitiv eine harte Nuss zu knacken. Bei Google haben wir unseren Discovery Service implementiert, für den alle unsere neuen APIs erstellt wurden. In der TL; DR-Version generieren wir eine JSON-Schema-ähnliche Spezifikation, die unsere Clients analysieren können - viele davon dynamisch.

Das Ergebnis bedeutet für den Entwickler einfachere SDK-Upgrades und für uns eine einfache / bessere Wartung.

Auf keinen Fall die perfekte Lösung, aber viele unserer Entwickler scheinen es zu mögen.

Weitere Informationen finden Sie unter dem Link (und sehen Sie sich unbedingt das Video an.)

Jonathanberi
quelle
Gibt es einen Standard für die Implementierung eines solchen Erkennungsdienstes für unsere eigenen APIs?
Çağatay Gürtürk
12

Faszinierend. Was Sie beschreiben, ist im Grunde das HATEOAS-Prinzip. Was ist HATEOAS, das du fragst? Lesen Sie dies: http://en.wikipedia.org/wiki/HATEOAS

Für Laien bedeutet HATEOAS Link folgen. Dieser Ansatz entkoppelt Ihren Client von bestimmten URLs und gibt Ihnen die Flexibilität, Ihre API zu ändern, ohne jemanden zu beschädigen.

Sam
quelle
4

Eine der Anforderungen, die erfüllt sein sollten, bevor Sie eine API als "RESTful" bezeichnen können, ist, dass es möglich sein sollte, eine generische Clientanwendung über diese API zu schreiben. Mit dem generischen Client sollte ein Benutzer auf alle Funktionen der API zugreifen können. Ein generischer Client ist eine Clientanwendung, die nicht davon ausgeht, dass eine Ressource eine bestimmte Struktur aufweist, die über die vom Medientyp definierte Struktur hinausgeht. Ein Webbrowser ist beispielsweise ein generischer Client, der HTML interpretiert, einschließlich HTML-Formulare usw.

Angenommen, wir haben eine HTTP / JSON-API für einen Webshop und möchten einen HTML / CSS / JavaScript-Client erstellen, der unseren Kunden eine hervorragende Benutzererfahrung bietet. Wäre es eine realistische Option, diesen Client als generische Clientanwendung zuzulassen? Nein. Wir möchten für jedes spezifische Datenelement und jeden spezifischen Anwendungsstatus ein spezifisches Erscheinungsbild bereitstellen. Wir möchten nicht das gesamte Wissen über diese Präsentationsspezifikationen in die API aufnehmen. Im Gegenteil, der Client sollte das Erscheinungsbild definieren und die API sollte nur die Daten enthalten. Dies bedeutet, dass der Client eine fest codierte Kopplung bestimmter Ressourcenelemente an bestimmte Layouts und Benutzerinteraktionen hat.

Ist dies das Ende von HATEOAS und damit das Ende von REST? Ja und nein .

Ja , denn wenn wir das Wissen über die API im Client fest codieren, verlieren wir den Vorteil von HATEOAS: Serverseitige Änderungen können den Client beschädigen.

Nein , aus zwei Gründen:

  1. "RESTful" zu sein ist eine Eigenschaft der API, nicht des Clients. Solange es theoretisch möglich ist , einen generischen Client zu erstellen, der alle Funktionen der API bietet, kann die API als RESTful bezeichnet werden. Die Tatsache, dass Clients die Regeln nicht einhalten, ist nicht die Schuld der API. Die Tatsache, dass ein generischer Client eine schlechte Benutzererfahrung haben würde, ist kein Problem. Warum ist es wichtig zu wissen, dass es möglich ist , einen generischen Client zu haben, wenn wir diesen generischen Client nicht haben ? Dies bringt mich zum zweiten Grund:
  2. Eine RESTful-API bietet Clients die Möglichkeit zu wählen, wie allgemein sie sein möchten, dh wie widerstandsfähig sie gegenüber serverseitigen Änderungen sein möchten. Clients, die eine hervorragende Benutzererfahrung bieten müssen, sind möglicherweise weiterhin anfällig für URI-Änderungen, Änderungen der Standardwerte und mehr. Clients, die Stapeljobs ohne Benutzerinteraktion ausführen, können anderen Arten von Änderungen standhalten.

Wenn Sie an praktischen Beispielen interessiert sind, lesen Sie mein JAREST-Papier . Der letzte Abschnitt handelt von HATEOAS. Sie werden sehen, dass mit JAREST selbst hochgradig interaktive und visuell attraktive Clients gegenüber serverseitigen Änderungen sehr widerstandsfähig sind, wenn auch nicht zu 100%.

www.admiraalit.nl
quelle
1

Ich denke, der wichtige Punkt bei HATEOAS ist nicht, dass es sich um eine Holy Grail-Clientseite handelt, sondern dass es den Client von URI-Änderungen isoliert. Es wird davon ausgegangen, dass Sie bekannte (oder entwickelte benutzerdefinierte) Link-Beziehungen verwenden, die es dem System ermöglichen wissen, welcher Link für ein Objekt die bearbeitbare Form ist. Der wichtige Punkt ist die Verwendung eines Hypermedia-fähigen Emdia-Typs (z. B. HTML, XHTML usw.).

Falkayn
quelle
0

Du schreibst:

Um die API sehr effizient zu gestalten, scheint eine Menge Link-Template für Abfrageparameter erforderlich zu sein, wodurch sich Out-of-Band-Informationen wieder einschleichen.

Wenn diese Linkvorlage in der vorherigen Anforderung angegeben wurde, gibt es keine Out-of-Band-Informationen. Beispielsweise verwendet ein HTML-Suchformular Link Templating ( /search?q=%@), um eine URL ( ) zu generieren /search?q=hateoas, aber dem Client (dem Webbrowser) ist nichts anderes bekannt als die Verwendung von HTML-Formularen und GET.

Nicholas Shanks
quelle
In der Tat gibt es keine Out-of-Band-Informationen - der Client ist für die Erweiterung der Uri-Vorlagen unter Verwendung der bereitgestellten Ressourcen- / Instanzdaten verantwortlich
fusi