Obwohl sie keiner wirklich neuen Idee folgen, erfreuen sich REST-APIs seit einiger Zeit erhöhter Beliebtheit auf Seiten der Industrie, aber auch kleinerer Projekte. Der Artikel erklärt, warum das so ist, und veranschaulicht den recht abstrakten Architekturansatz an einem fasslichen Beispiel.
Fast 15 Jahre, bevor Tim Berners-Lee und Robert Cailliau den ersten Webserver des World Wide Web in Betrieb nahmen, publizierte James E. White die Idee des Remote Procedure Call (RPC) im RFC 707 [1], das 1976 erschien. Ein RPC sollte es einem Computer ermöglichen, eine Funktion auf einem entfernten Computer auszuführen. Die Maschine-zu-Maschine-Kommunikation (M2M) nahm damit konkrete Züge an.
Berners-Lee dachte beim Entwickeln des HTTP-Protokolls und der Hypertext Markup Language (HTML) hingegen an menschliche Nutzer, die durch weltweit verteilte Dokumente navigieren, also an die Mensch-Maschine-Schnittstelle.
Der wesentliche Unterschied zwischen beiden Architekturen besteht darin, wie sich dem Client die Ressourcen auf dem Server erschließen. RPC verlangt vom Client sehr spezifische Kenntnisse darüber, wie er auf die entfernten Ressourcen auf dem Server zugreift. Hier muss der Entwickler die Protokollspezifikation ausführlich studieren, um den Sinn der Datenelemente für Ein- und Ausgaben zu verstehen.
Im Web liest dank des textbasierten HTML-Formats hingegen kaum ein Besucher die Bedienungsanleitung für eine Webseite durch, bevor er den Dienst verwendet. Der Anwender schließt aus dem, was er auf der Webseite sieht, intuitiv darauf, wie er diese benutzen soll. Bei Maschinen läuft das anders. In der M2M-Kommunikation muss der Entwickler durch genaue Spezifikationen festlegen, wie eine Maschine die Daten auslegt.
Maschinen reden mit
Den Erfindern des WWW wurde relativ schnell klar, dass nicht nur Humanoide die Möglichkeiten der Hypermedia-Welt nutzen. Sie konzipierten das Web von Anfang an für hohe Skalierbarkeit, einfache Benutzbarkeit, Erweiterbarkeit und als verteiltes Hypermedia.
Um der durch diesen Ansatz drohenden Beliebigkeit zu entkommen, nahmen die Entwickler bestimmte Einschränkungen vor, entwarfen etwa HTTP als zustandsloses Protokoll. Das heißt, dass sich der Server keine Gedanken machen muss, an welchem Punkt im Arbeitsfluss sich seine Clients aktuell befinden. Auf diese Art kann ein Server zahlreiche Clients mit geringem Aufwand verwalten. Das Protokoll ist zugleich sehr einfach gehalten, es umfasst nur wenige Anfrage-Methoden (Verben) wie »GET« und »HEAD« sowie, je nach Server, die optionalen Verben »POST«, »PUT«, »DELETE«, »OPTIONS«, »TRACE« und »CONNECT«[2].
Den Schlüssel zum Erfolg des WWW brachte jedoch das Hypermedia-Format, das Anwendungslogik und Darstellung vereint. Mit Hilfe von HTML-Oberflächen liefern Server gleich die Clients für ihre Webanwendung mit. Das HTML-Format erlaubt es zudem, Ressourcen zu verknüpfen, sodass Nutzer interaktiv durch die Anwendung navigieren und von HTML-Seite zu HTML-Seite springen.
Diese relativ klar definierten Einschränkungen und die selbsterklärende Logik des Web sollten eigentlich auch gut für Maschinenschnittstellen funktionieren. In der Praxis nehmen aber nur wenige APIs bisher darauf Rücksicht. Zwar nutzen immer mehr das HTTP-Protokoll, meist mischen sie aber die Protokolllogik mit der Anwendungslogik.
Auch in das Datenformat müssen Entwickler sich meist aufwändig einarbeiten. Das liegt fern jener selbsterklärenden HTML-Navigation über klar gekennzeichnete Verknüpfungen von Ressourcen.
REST zu Hilfe
Im Jahr 2000 plädierte Roy T. Fielding in seiner lesenswerten Dissertation [3] dafür, die vier Prinzipien der hohen Skalierbarkeit, einfachen Benutzbarkeit, Erweiterbarkeit und selbstbeschreibenden Hypermedia zur Grundlage einer effizienten Webarchitektur zu machen und in Form des Representational State Transfer (REST) konsequent umzusetzen. Obschon beinahe zwei Jahrzehnte diskutiert, kommt REST aber erst seit einigen Jahren in der Industrie zum Einsatz.
Eine Ursache liegt auch darin, wie Entwickler traditionell APIs entwerfen. Oft legen Architekten zu früh die Perspektive fest: Mal stehen das Frontend, mal das Datenbankdesign und mal das Datenformat im Vordergrund. Im Ergebnis entstehen schwer zu erschließende und zueinander inkompatible APIs, die mitunter dennoch sehr ähnliche Funktionen anbieten. REST kann helfen, diese Redundanzen aufzulösen und ein nachhaltiges Betriebskonzept zu ermöglichen.
Überbau
Den Kern des REST-Ansatzes sieht Fielding in einer zusätzlichen Service-Ebene zwischen den beteiligten Komponenten, um die Nutzersicht möglichst unabhängig von der spezifischen technischen Infrastruktur zu gestalten. Die Abstraktion von der Technik unter Berücksichtigung der Nutzersicht vereinfacht auch zwangsläufig die Systemarchitektur aus der Client-Perspektive. In der Folge kann ein externer Entwickler wesentlich besser nachvollziehen, wie ein Client mit der Anwendung kommuniziert.
Insgesamt will Fielding also die Systemarchitektur vereinfachen, um den Betrieb und die Weiterentwicklung nicht nur der Anwendung, sondern eben auch von Tausenden unabhängigen Clients effizient und nachhaltig zu ermöglichen. Die Abstraktion findet dabei nicht mehr ausschließlich auf Ebene der Datenbanken (Postgres, MySQL) und Webserver (Apache, Nginx) statt, sondern auch in den Datenformaten, die sich an Standards, Konventionen, RFCs und registrierten Mediatypen orientieren.
Fielding macht für REST vier notwendige Bedingungen fest:
- Es muss Ressourcen identifizieren.
- Es darf Ressourcen nur über abstrakte Repräsentationen verändern.
- Es liefert selbsterklärende Beschreibungen.
- Es setzt auf das Hypermedia-Format, das den Anwendungsstatus steuert.
Wohl auch weil Fieldings Beschreibung recht abstrakt blieb, ließ eine praktische Umsetzung lange auf sich warten. Erst seit viele API-Entwickler die schmerzlichen Erfahrungen gemacht haben, die Fielding vorhersah, übersetzen sie sein Konzept in die Praxis.
Endlich greifbar
Heute lässt sich REST – angewandt auf das Web – etwa so definieren: Zu den Ressourcen gehören Datenbankeinträge, Bilder, Dokumente oder andere elektronische Daten. Sie lassen sich über eindeutige Unified Ressource Identifier (URI) adressieren. Diese müssen für den Nutzer nicht unbedingt gut lesbar sein, schon gar nicht in einer Maschine-zu-Maschine-Schnittstelle. Dennoch sollte es möglich sein, eine Ressource einem URI eindeutig zuzuordnen.
Ressourcen wie etwa Datenbankeinträge manipuliert der Entwickler nicht direkt, weil REST sie zunächst in einer Darstellungsschicht abstrahiert und so vom Datenbankdesign entkoppelt.
Die eingesetzten Datenformate enthalten zugleich alle Informationen und Funktionen, um die Anwendungslogik zu erschließen. Weil REST Standards verwendet, hört das Anwendungsverhalten auf bekannte Mechanismen und beschreibt sich die Schnittstelle quasi selbst. So kommt etwa das »method«-Attribut in einem Formular zum Einsatz und leuchtet eine Verbindung zu einer anderen Ressource mittels »href«-Attribut unmittelbar ein. Nicht zuletzt überführt HTML mit seinen wohldefinierten Elementen, zu denen Links und Formulare gehören, die Webanwendung von einem kontrollierten Zustand zum nächsten.
REST-API entwerfen
REST ist lediglich ein Architekturmodell, das die konkrete Implementierung nicht vorgibt. Es erfordert einen gewissen Aufwand, die Anwendungslogik in das REST-Schema zu überführen. Doch sichert dieser erste Schritt bereits die halbe Miete. Der Mehraufwand zahlt sich aus, wenn sich externe Entwickler oder neue Mitarbeiter in die API-Logik einarbeiten. Gerade bei offenen APIs für eine breite Entwicklergemeinde ist dies zudem oft ein entscheidender Akzeptanzfaktor.
Bei den weiteren Schritten hilft ein strukturierter Designprozess ([4], [5]). Im zweiten Schritt entwirft der Entwickler das Schnittstellenmodell. Er legt fest, welche Daten über die Schnittstelle laufen und in welchem Zustand sich die Anwendung nach jedem Schritt befindet. Dabei treten auch die Beziehungen zwischen den beteiligten Rollen hervor, die später als Links auftauchen.
Im dritten Schritt definiert er möglichst Standards für die Bezeichner, zum Beispiel von Links oder Mediatypen. Unzählige registrierte Bezeichner stehen bereits zur Verfügung ([6], [7], [8]). Ein API lässt sich wesentlich besser integrieren, wenn sich die Bezeichner in erwarteter oder bereits bekannter Weise verhalten. In enger Abstimmung mit den Bezeichnern erfolgt die Auswahl des Medientyps. Meist lässt es sich nicht vermeiden, mehrfach über die Schritte 2 und 3 zu iterieren, bis das Resultat erfreut.
Die eigene Interpretation gilt es schließlich zu dokumentieren. Als Ergebnis wartet ein Anwendungsprofil, das im besten Fall aus einem registrierten Standardprofil mit geringen Anpassungen besteht. Erst im vierten Schritt geht es darum, das API zu implementieren.
OData
REST punktet vor allem bei Internetanwendungen mit großen Nutzerzahlen und Millionen paralleler Zugriffe, was erklärt, warum gerade die großen Technologie-Anbieter verstärkt auf REST setzen. Im Bereich der Datenformate bemüht sich zum Beispiel das OASIS Open Data Protocol (OData) Technical Committee [9] um eine Standardisierung. Viele große Hersteller unterstützen die Initiative, darunter Red Hat, Microsoft, IBM und SAP.
OData ist ein relativ umfangreiches Protokoll und erfordert einige Einarbeitungszeit. Der REST-basierte Standard baut auf HTTP, das Atom Publishing Protocol [10] sowie Json [11] auf und nutzt konsequent URIs, um Ressourcen zu adressieren. Die betont breit aufgestellten Anwendungsfälle umfassen relationale Datenbanken, Dateisysteme, Contentmanagement-Systeme aber auch traditionelle Webseiten.
Im Februar 2017 hatte das ISO Joint Technical Committee den OASIS OData Standard for Open Data Exchange (ISO/IEC 20802:1 [12] und 20801:2 [13]) angenommen. Vor diesem Hintergrund ist OData eher ein industriepolitisches Programm und im Umfeld von Großunternehmen oder Behörden interessant.
Open API
Open API [14] ist eine Initiative mit dem Schwerpunkt auf Hersteller-neutralen API-Beschreibungsformaten [15]. Grundlage lieferte die Swagger-Spezifikation [16]. Die Beschreibungssprache soll unabhängig von der Programmiersprache das Entwickeln von APIs erlauben, die sowohl Menschen als auch Maschinen schnell erfassen. Die Spezifikation steht unter der Apache-2.0-Lizenz und zählt unter anderem Google, Paypal, Red Hat und Microsoft zu ihren Supportern. Als besonders hilfreich erweisen sich die zahlreichen unterstützenden Werkzeuge [17] wie zum Beispiel der Yaml-Swagger-Editor in Abbildung 1.

Abbildung 1: Der Yaml-Swagger-Editor ermöglicht den Entwurf eines API direkt im Webeditor, das Beispiel zeigt das Uber-API.
Ein Highlight ist der Swagger Petstore (Abbildung 2, [18]), ein Beispielserver, der die Spezifikation veranschaulicht und Experimente erlaubt. Open API ist sehr anschaulich dokumentiert, was die Einarbeitungszeit erheblich verkürzt, und eignet sich selbst für kleinere Projekte.
Raml
Die RESTful-API Modeling Language (Raml, [19]) geht einen ganz ähnlichen Weg wie Open API. Hinter der Initiative stehen unter anderem Mulesoft, VMware und Cisco. Raml verspricht den gesamten Lebenszyklus eines API – vom Design bis zum Ausrollen – zu unterstützen. Das gelingt mit Hilfe der gut aufbereiteten Dokumentation [20] und der angebotenen Werkzeuge recht ordentlich.
Ähnlich wie der Yaml-Swagger-Editor hat Mulesoft einen Raml-Web-API-Designer entwickelt (Abbildung 3, [21]). Die entworfenen API-Elemente lassen sich direkt über einen Mocking-Service ausprobieren. Dafür lädt Mulesoft den API-Entwurf in einen Webservice und führt ihn aus. Alternativ bietet Mulesoft eine Entwicklungsumgebung namens API-Workbench [22] quelloffen, aber unter einer proprietären Lizenz an.

Abbildung 3: API-Management als Webservice – im Raml-API-Manager lassen sich API-Elemente per Mocking-Service testen.
RESTful mit Ruby und Sinatra
Als einfaches Beispiel soll ein RESTful-API eine Liste mit Namen verwalten. Beim Entwurf half der Raml-API-Designer. Hiermit entwarf der Autor zunächst das API und testete innerhalb des Raml-API-Designers in einer Mocking-Umgebung, ob es formal die richtigen Ein- und Ausgaben liefert. Erst dann schrieb er überhaupt eine Zeile Code. Der entstand auf Grundlage der Raml-Spezifikation 0.8, ihn zeigt Listing 1. Dank der übersichtlichen Yaml-basierten Darstellung konzentriert sich der Entwickler komplett auf die API-Funktionalitäten. Die Eigenheiten einer Programmiersprache hält er aus diesem Prozess heraus. Das Tutorial unter [23] gibt eine gute Einführung dazu, wie er ein REST-API am besten entwickelt.
Listing 1
api.raml
01 #%Raml 0.8
02 title: Contacts
03 version: 0.1
04 #baseUri: http://www.rve.com/contactshelf
05 baseUri: https://mocksvc.mulesoft.com/mocks/d4c4356f-0508-4277-9060-00ab6dd36e9b/contactshelf
06 /contacts:
07 get:
08 description: Die Liste vorhandener Kontakte abrufen
09 responses:
10 200:
11 body:
12 application/json:
13 example: |
14 {
15 "data": [
16 {
17 "id": "1",
18 "name": "Rheik",
19 "link": "http://localhost:4567/contacts/Rheik"
20 },
21 {
22 "id": "2",
23 "name": "Paul",
24 "link": "http://localhost:4567/contacts/Paul"
25 },
26 {
27 "id": "3",
28 "name": "Emil",
29 "link": "http://localhost:4567/contacts/Emil"
30 }
31 ],
32 "success": true,
33 "status": 200
34 }
35 /{name}:
36 get:
37 description: Einen spezifischen Kontakt abrufen
38 responses:
39 200:
40 body:
41 application/json:
42 example: |
43 {
44 "data": {
45 "id": "1",
46 "name": "Rheik",
47 "link": "http://localhost:4567/contacts/Rheik"
48 },
49 "success": true,
50 "status": 200
51 }
52 /new:
53 post:
54 description: Einen neuen Kontakt hinzufügen
55 body:
56 application/json:
57 example: |
58 {
59 "data": {
60 "name": "Franz",
61 "link": "http://localhost:4567/contacts/Franz"
62 }
63 }
64 responses:
65 200:
66 body:
67 application/json:
68 example: |
69 { "message": "Kontakt wurde korrekt übertragen." }
70 /{id}:
71 delete:
72 description: Einen spezifischen Kontakt löschen
73 responses:
74 200:
75 body:
76 application/json:
77 example: |
78 { "message": "Kontakt id = <<resourcePathName>> gelöscht." }
79 404:
80 body:
81 application/json:
82 example: |
83 { "message": "Kontakt id = <<resourcePathName>> nicht gefunden." }
Die Daten für den Dienst stecken in einer SQlite-Datenbank. Diese füllt das Skript aus Listing 2 auf der Kommandozeile mit drei Beispieleinträgen und listet sie anschließend auf.
Listing 2
SQlite-Datenbank mit Beispieleinträgen erzeugen
01 $ sqlite3 contacts.sqlite "CREATE TABLE contacts (id INTEGER PRIMARY KEY, name, link);"
02 $ sqlite3 contacts.sqlite "INSERT INTO contacts (name, link) VALUES ('Rheik', 'http://localhost:4567/contacts/Rheik');"
03 $ sqlite3 contacts.sqlite "INSERT INTO contacts (name, link) VALUES ('Paul', 'http://localhost:4567/contacts/Paul');"
04 $ sqlite3 contacts.sqlite "INSERT INTO contacts (name, link) VALUES ('Emil', 'http://localhost:4567/contacts/Emil');"
05 $ sqlite3 contacts.sqlite "SELECT * FROM contacts;"
06 1|Rheik|http://localhost:4567/contacts/Rheik
07 2|Paul|http://localhost:4567/contacts/Paul
08 3|Emil|http://localhost:4567/contacts/Emil
09 $
Das Ruby-Skript in Listing 3 zeigt das Programm für einen Sinatra-Server, der auf Grundlage dieser Datenbank ein einfaches REST-API zur Verfügung stellt. Tatsächlich RESTful ist dieses API nur im Ansatz, da das im Beispiel eingesetzte Json-Format weder standardisiert ist noch auf ein Schema verweist noch wirklich Hypertext-basiert ist. Hier würde das entsprechende Hypermedia-Schema zum Einsatz kommen, worauf das Beispiel der Anschaulichkeit zuliebe verzichtet.
Listing 3
contacts.rb
01 require 'rubygems'
02 require 'sinatra'
03 require 'sinatra/json'
04 require 'uri'
05 require 'active_record'
06
07 ActiveRecord::Base.establish_connection(
08 :adapter => 'sqlite3',
09 :database => 'contacts.sqlite'
10 )
11
12 class Contact < ActiveRecord::Base
13 end
14
15 get '/contacts' do
16 @contacts = Contact.all
17 @response_message = {data: @contacts, success: true, status: 200}
18 json @response_message
19 end
20
21 get '/contacts/:name' do
22 @name = params['name']
23 @contact = Contact.where(name: @name).first
24 @response_message = {data: [@contact], success: true, status: 200}
25 json @response_message
26 end
27
28 post '/contacts/new' do
29 @data = JSON.parse(request.body.read)['data']
30 puts @data.inspect
31 if @data['name'] and @data['link'] then
32 @contact = Contact.new(name: @data['name'], link: @data['link'])
33 @contact.save
34 end
35 @response_message = { "message": "Kontakt #{@data['name']} erstellt." }
36 json @response_message
37 end
38
39 delete '/contacts/:id' do
40 @id = params['id']
41 @contact = Contact.find_by_id(@id)
42 if @contact then
43 Contact.delete(@contact.id)
44 @response_message = { "message": "Kontakt id = #{@contact.id} gelöscht." }
45 else
46 @response_message = { "message": "Kontakt id = #{@contact.id} nicht gefunden." }
47 end
48 json @response_message
49 end
50
51 options '/' do
52 # Aktuell unterstützte HTTP Verben
53 response.headers["Allow"] = "HEAD,GET,POST,DELETE,OPTIONS"
54 204
55 end
Einfacher Zugriff
Vorausgesetzt die Datenbank »contacts.sqlite« liegt im selben Verzeichnis, lässt sich der Sinatra-Server mit »ruby contacts.rb« starten. Den Client mimt Curl, der Weballrounder für die Kommandozeile. Um die bereits vorhandenen Einträge in der Datenbank aufzulisten, greift Curl auf die URL »http://localhost: 4567/contacts« zu. Diese liefert die Daten dann im Json-Format zurück.
Die Option »-v« zeigt alle HTTP-Parameter, aus denen insbesondere hervorgeht, dass der Content-Typ »application/json« ist (Listing 4).
Listing 4
Curl-Zugriff
01 $ curl -v "http://localhost:4567/contacts"
02 * Trying ::1...
03 * TCP_NODELAY set
04 * Connected to localhost (::1) port 4567 (#0)
05 > GET /contacts HTTP/1.1
06 > Host: localhost:4567
07 > User-Agent: curl/7.51.0
08 > Accept: */*
09 >
10 < HTTP/1.1 200 OK
11 < Content-Type: application/json
12 < Content-Length: 382
13 < X-Content-Type-Options: nosniff
14 < Server: WEBrick/1.3.1 (Ruby/2.3.3/2016-11-21)
15 < Date: Thu, 30 Mar 2017 18:48:49 GMT
16 < Connection: Keep-Alive
17 <
18 * Curl_http_done: called premature == 0
19 * Connection #0 to host localhost left intact
20 {"data":[{"id":1,"name":"Rheik","link":"http://localhost:4567/contacts/Rheik"},{"id":2,"name":"Paul","link":"http://localhost:4567/contacts/Paul"},{"id":3,"name":"Emil","link":"http://localhost:4567/contacts/Emil"}],"success":true,"status":200}
21 $
Das »”link”«-Attribut in der Liste lässt ahnen, wie der Aufruf für einen einzelnen Eintrag lauten müsste. Diesen holt Curl über »curl “http://localhost:4567/contacts/Rheik”« ab. Das korrespondiert mit der Methode »get ‘/contacts/:name’« im Sinatra-Skript und mit »/{name}:« im Raml-Entwurf.
Einen neuen Eintrag erstellt der Aufruf von Curl mit der »POST«-Methode (Listing 5), hier bricht das Programm jedoch mit der REST-Logik. Intuitiver wäre ein »POST« auf die URL der Kontaktressource »http://localhost:4567/contacts/Jim«. Allerdings erwarten viele Entwickler einen festen Pfad (»/new«), wenn die Ressource noch fehlt.
Listing 5
Curl und POST
01 $ curl -H "Content-Type: application/json" -X POST -d '{"data": {"name": "Jim", "link": "http:://localhost:4567/contacts/Jim"}}' http://localhost:4567/contacts/new
02
03 {"message":"Kontakt Jim erfolgreich erstellt."}
Formal richtig wäre es, den »POST« auf »/contacts« zu senden. Am besten sollte der Entwickler eine Lösung finden, die schnell ins Auge springt.
Am Ende lässt sich sicherlich leicht erraten, was der folgende Aufruf bewirkt:
curl -H "Content-Type: application/json" -X DELETE http://localhost:4567/contacts/6
Er löscht den Eintrag mit der ID »6«. Anders als der Name ist die ID eindeutig.
Mit Hilfe der »options«-Methode (ab Zeile 51, Listing 3) teilt der Server auf eine entsprechende Anfrage hin mit, welche HTTP-Verben er unterstützt (»Allow«). Die Antwort erfordert den Curl-Parameter »-i«, da die Ausgabe andernfalls nicht erscheint (Listing 6).
Listing 6
Optionen abfragen
01 $ curl -i -X OPTIONS http://localhost:4567/ 02 HTTP/1.1 204 No Content 03 Allow: HEAD,GET,POST,DELETE,OPTIONS 04 X-Content-Type-Options: nosniff 05 Server: WEBrick/1.3.1 (Ruby/2.3.3/2016-11-21) 06 Date: Thu, 30 Mar 2017 19:11:56 GMT 07 Connection: Keep-Alive 08 $
Fazit
REST ist eine abstrakte Idee, um das Verhalten einer Software-Architektur besser zu strukturieren. Der Ansatz verlangt aber Disziplin und den Einzug einer zusätzlichen Abstraktionsebene über die gewünschte Lösung. Das passt nicht jedem. Es hängt vom Anspruch an das API ab, wie sinnvoll der zusätzliche Aufwand ist: Wie lange will sie der Entwickler pflegen, wie schnell sollen sich neue Entwickler einarbeiten, wie kompatibel zu anderen Lösungen soll es sein – um nur einige der grundsätzlichen Fragen zu nennen.
Das Beispiel-API auf Basis des Sinatra-Servers sollte die Idee veranschaulichen. Um daraus ein vollständiges RESTful-API zu machen, müsste der Entwickler das Raml-Design ausfeilen und den Standard für das Datenformat sinnvoll wählen.
Der Vorteil von REST besteht im Konzept des “Hypertext As The Engine Of Application State” (HATEOAS). Grob heißt das: Jeder Client sollte aufgrund des vorliegenden Hypertextes den für ihn aktuellen Zustand der Anwendung kennen und über die Hypertext-Mechanismen zum nächsten gelangen.
Das Beispiel setzt das nur ungenügend um. Aus der Antwort liest der Client zwar, wie er an einen einzelnen Kontakt kommt. Aber wie er diesen erzeugt und die Daten dafür strukturieren müsste, erfährt er daraus nicht. Solche Hinweise in das Format selbst zu integrieren wäre der nächste Schritt.
Einige Standardformate bieten an, »POST«-Vorlagen oder Schema-Beschreibungen in das Protokoll aufzunehmen. Hier lohnt ein Blick auf die registrierten Formate und Protokolle wie IANA [6], Schema.org [7] oder Alps.io [8].
Infos
-
A High-Level Framework for Network-Based Resource Sharing: https://tools.ietf.org/html/rfc707
-
Request for Comments (RFC) zum Hypertext Transfer Protocol (HTTP/1.1): https://tools.ietf.org/html/rfc7231
-
Roy T. Fielding, “Architectural Styles and the Design of Network-based Software Architectures”, University of California, 2000: http://roy.gbiv.com/pubs/dissertation/top.htm
-
Lennard Richardsen und Mike Amundsen, “RESTful Web APIs: Services for a Changing World”: O’Reilly, 2013
-
Mike Amundsen, “Building Hypermedia APIs with HTML5 & Node – Creating Evolvable Hypermedia Applications”: O’Reilly, 2011
-
Bei IANA registrierte Mediatypen: https://www.iana.org/assignments/media-types/media-types.xhtml
-
Schemata für strukturierte Daten im Internet: http://schema.org
-
Application-Level Profile Semantics (Alps): http://alps.io/spec/index.html
-
OData-Standard von OASIS: https://www.oasis-open.org/committees/tc_home.php?wg_abbrev=odata
-
Atom Publishing Protocol (Atom Pub): https://tools.ietf.org/html/rfc5023
-
Javascript Object Notation (Json): http://www.json.org
-
OData-Standard, Part 1, Core (ISO/IEC 20802-1:2016): https://www.iso.org/standard/69208.html
-
OData-Standard, Part 2, OData Json Format (ISO/IEC 20802-2:2016): https://www.iso.org/standard/69209.html
-
Open-API-Initiative: https://www.openapis.org
-
Tim Schürmann, “Todschick”: Linux-Magazin 08/16, S. 82
-
Open-API-Spezifikation: https://github.com/OAI/OpenAPI-Specification
-
Swagger-Tools: http://swagger.io/open-source-integrations/
-
Swagger Petstore: http://petstore.swagger.io
-
RESTful API Modeling Language: http://raml.org
-
Raml-Version 0.8: https://github.com/raml-org/raml-spec/blob/master/versions/raml-08/raml-08.md
-
Mulesoft API-Designer: https://www.mulesoft.com/platform/api/anypoint-designer
-
Mulesoft API-Workbench: http://apiworkbench.com
-
Raml-100-Tutorial: http://raml.org/developers/raml-100-tutorial








