REST Kritik #2: REST ist zu technisch

2018-01-02 von Thomas Bayer

Fast alle öffentlichen Schnittstellen sind REST basierte APIs. Ein Grund für die weite Verbreitung von REST sind die geringen Hürden, die es für den Aufruf eines APIs zu überwinden gilt. Für einfache Aufrufe genügt ein Browser und Clients können in fast jeder Programmiersprache, selbst in Skriptsprachen wie Perl und PHP mit nur wenigen Zeilen Code verwirklicht werden. Einer der größten Vorteile von REST ist der einfache Einstieg selbst für Nicht-Informatiker.

Dank des einfachen Einstiegs hat REST auf Remote Procedure Calls basierte Middleware stark verdrängt. Die Mitte der Nuller-Jahre populären Web Services waren komplex und konzeptionell überlagen. Die Web Services Standards wurden vom Semantic Web beeinflusst und fanden den Höhepunkt der Komplexität in einer Reihe von Standards rund um die Web Services Security. REST und SOAP sind beide um die Jahrtausendwende entstanden und wurden beide vom W3C und vom Semantik Webs beeinflusst. Daher verwundert es kaum, dass auch REST Ideen des Semantik Webs aufgreift, beispielsweise verlinkte Hypermedia-Dokumente und MIME-Types. Dieses Erbe wird dazu führen, dass auch die Verbreitung von REST nachlassen wird.

Dass REST sehr technisch ist möchte ich an einem Vergleich mit RPC basierter Middleware erläutern. Als Beispiel für RPC verwende ich die SOAP basierten Web Services. Um alle Missverständnisse auszuräumen: Ich möchte SOAP auf keinen Fall zurück. Es ist nur so, dass SOAP Kenntnisse heute noch verbreiteter sind als Google RPC oder CORBA und ich daher gezwungen bin SOAP zu verwenden.

Zentral ist bei vielen RPC Technologien die Schnittstellenbeschreibung. Im Beispiel unten ist dies ein WSDL Dokument, aus dem mittels eines Generators Code für den Client und den Server erzeugt wird. Für den Server ist dies bei den Web Services eine Vorlage für die Implementierung von Services. Für den Client wird eine oft Stub genannte Bibliothek erzeugt. Diese Client-Bibliothek kümmert sich um alles Technische, was für einen Aufruf notwendig ist. Dazu gehört die Serialisierung zwischen Java und XML sowie die Kommunikation über HTTP.

RPC Codegenerator

Dank der Client-Bibliothek können Funktionen des Servers einfach aufgerufen werden. Der Code des Web Service-Aufrufs unten in der Abbildung unterscheidet sich nicht von einem lokalen Aufruf einer Funktion oder einer Methode.

RPC Aufruf

Bis der erste Aufruf durchgeführt werden kann, muss bei den Remote Procedure Calls aus der Schnittstellenbeschreibung erst die Client Bibliothek erstellt werden. Das Erzeugen des Codes, das Kompilieren und Einbinden wird meist mit Hilfe eines Build-Werkzeuges automatisiert. Das Aufsetzen des Builds z.B. mit Maven oder make ist der komplizierteste Arbeitsschritt bei RPC. Das eigentliche Programmieren ist einfach. Der Entwickler benötigt für die Arbeit mit SOAP weder XML noch HTTP Kenntnisse. Netzwerk- und Anwendungsfehler werden in Exceptions der jeweiligen Programmiersprache abgebildet. Die Tatsache, dass die Kommunikation über das Netz erfolgt wird bei RPC einfach in der Stub-Bibliothek „weggekapselt“. Dass das Netz nicht sichtbar ist, war bei RPC immer auch ein Kritikpunkt.

Bei REST werden ganz bewusst die Eigenschaften von HTTP für die Kommunikation verwendet. Beispielsweise muss der Client HTTP Status Codes interpretieren anstatt Exceptions abzufangen. Die Abbildung unten zeigt einen Client, der eine HTTP Bibliothek für seine Aufrufe verwendet.

REST Client mit HTTP Bibliothek

Das Listing unten zeigt typischen REST Client Code. Im Gegensatz zum RPC Einzeiler ist der Aufruf aufwendiger und technischer.

GetMethod method = new GetMethod("http://api.predic8.de/shop/products/65"); method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(3, false)); int sc = client.executeMethod(method); if (sc != HttpStatus.SC_OK) { System.err.println(method.getStatusLine()); } byte[] responseBody = method.getResponseBody();

Klar, inzwischen gibt es mächtige REST Client Bibliotheken wie z.B. Unirest:

json = Unirest.get("http://api.predic8.de/shop/products/65").asJson()

Aber selbst mit Unirest muss sich der Client-Entwickler mit Status Codes, Mime-Typen und HTTP Methoden auseinandersetzen. Der Client Entwickler benötigt Kenntnisse:

  • des HTTP Protokolls
  • des Formates der Repräsentationen z.B. JSON
  • der REST Prinzipien

Als REST Befürworter könnte man jetzt argumentieren, dass man sich auch bei REST nicht um HTTP kümmern muss. Es gibt ja auch für REST Sprachen zur Schnittstellenbeschreibung wie z.B. Swagger bzw. Open API. Aus einer Swagger Beschreibung kann man sich eine Client-Bibliothek generieren, mit der ein Aufruf in einer Zeile möglich ist:

Product product = api.getProduct(65);

Wer Swagger macht, macht aber kein REST mehr. Bei REST dreht sich alles um Hypermedia, Repräsenationen und Ressourcen. Vom all dem ist in einem aus Swagger generierten Client nichts mehr zu finden. Gerade weil sich die Entwickler wieder nach der Einfachheit von RPC sehnen wird Swagger immer populärer.

Trotz des verführerisch einfachen Einstiegs ist REST zu komplex und zu technisch für viele Anwendungen im Unternehmen. Eine Schnittstelle im Großkonzern ist nicht vergleichbar mit einem einfachen öffentlichen API, welches nur in begrenztem Umfang Funktionalitäten anbietet. REST ist die Technologie der Wahl für simple öffentliche Schnittstellen. Für etwas komplexere APIs sollte man wieder Remote Procedure Calls zum Beispiel Google RPC in Erwägung ziehen, anstatt für alles blind dem Hype folgend REST zu verwenden.