Denkt man an Web-APIs, dann verbindet man das zugehörige Kommunikationsmodell meist mit RESTful Requests und Responses. Dies ergibt in vielen Fällen sicherlich auch Sinn, aber eben nicht in allen! Was ist z.B., wenn auf Seiten des Clients komplexe Abfragen anstehen, die sich nicht so einfach über simple “Ressourcen” abbilden lassen. Wie geht man damit um, wenn auf dem Server lang laufende Aktionen angestoßen werden, auf deren Abarbeitung der Client nicht unbedingt warten möchte? Und muss es eigentlich immer clientseitiges “Pull” sein oder ergibt nicht serverseitiges “Push” via WebSocket in vielen Anwendungsfällen mehr Sinn? Die Session zeigt anhand ausgewählter praxisnaher Use Cases, wie man durch verschiedene Patterns das klassische RESTful Request-/Response-Modell seines Web-API sinnvoll erweitern kann, und so zu deutlich eleganteren und performanteren Lösungen kommt.
Das Product Goal oder "Ohne Ziele laufen eben alle in die Richtung, die ihnen...
Web-API-Design jenseits von REST und Request/Response
1. Lars Röwekamp | CIO New Technologies | open knowledge GmbH
#WISSENTEILEN
@_openKnowledge
@mobileLarson
Web APIs
jenseits von REST & Request/Response
3. ÜBER MICH
Wer bin ich - und wen ja, wie viele?
• CIO New Technologies
• Enterprise & Mobile
• Autor, Speaker, Coach & Mentor
• Snowboard & MTB Enthusiast
• Mehrfacher Vater, einfacher Ehemann
Lars Röwekamp (a.k.a. @mobileLarson)
#WISSENTEILEN
LR
36. #WISSENTEILEN
public class BooksResource {
@Produces("multipart/mixed")
public Map<String, Object> getBooks() {
Map<String, Object> map
= new LinkedHashMap<String, Object>();
map.put("text/xml", new JaxbBook());
map.put("application/json", new JSONBook());
map.put("application/octet-stream", imageInputStream);
return map;
}
...
}
Piggy Back mit APACHE CXF
42. #WISSENTEILEN
Was steckt dahinter?
• Paradigmenwechsel in der Kommunikation
• Abkehr vom klassischen Request/Response
• Client meldet sich am Server an
• Server kann Client jederzeit “Daten“ schicken
• Session kann von beiden Seiten beendet werden
Serverseitige Ereignisse
45. #WISSENTEILEN
Was sind Server-Sent Events?
• senden von Daten vom Server zum Client
• nutzt normales HTTP Protokoll
• built-in Support für Reconnection
• via JS, falls kein Browser Support vorhanden
• lediglich UTF-8 Daten (keine Binärdaten)
• Limitierung der offenen Connections
Server-Sent Event 1x1
58. #WISSENTEILEN
// Bestellungen: Kaffee mit Milch zu 2 €
GET /orders?type=coffee&ingredient=milk&price=2
Komplexe Abfragen mit REST
btw: UND oder ODER oder UND/ODER?
59. #WISSENTEILEN
// Bestellungen: Kaffee mit Milch oder günstiger als 2 €
GET /orders?type=coffee;ingredient=milk,price<=2
Komplexe Abfragen mit REST
btw: Klammerung?
60. #WISSENTEILEN
// Bestellungen: Kaffee mit Milch oder günstiger als 2 €
// RQL query ... (must possibly be encoded!)
GET /orders?query=
and(eq(type,coffee),
or(eq(ingredients,MILK),lt(price,2))
// RQL alternative query – FIQL (URI friendly) - ...
GET /orders?query=
type==coffee;(ingredients==MILK,price=lt=2)
Komplexe Abfragen mit RQL*
*https://github.com/persvr/rql
64. #WISSENTEILEN
Wer genau ist eigentlich dieser „Luke“ und in welchen Filmen
hat er mitgespielt?
GET /people/1/films (falls es der Endpoint anbietet)
GET /films/1
GET /films/2
GET /films/3
Komplexe Abfragen mit REST
65. #WISSENTEILEN
Wer genau ist eigentlich dieser „Luke“ und in welchen Filmen
hat er mitgespielt und auf welchen Raumschiffen ist er darin gefahren?
GET /people/1/starships (falls es der Endpoint anbietet)
GET /starships/12
GET /starships/22
Komplexe Abfragen mit REST
66. #WISSENTEILEN
Wie alt ist Luke und welche Haarfarbe hat er?
Mit welchem Spruch wurden die Filme eröffnet, in denen er mitgespielt hat?
Und wie teuer waren überhaupt die Raumschiffe auf denen er gefahren ist?
GET /?F#CKING/detail (n+1 problem)
GET /?F#CKING/all (job problem)
Komplexe Abfragen mit REST
68. #WISSENTEILEN
Motivation:
„ We see a conflict between the desire to load all
information in a single round trip while keeping REST
resources well isolated.”
Komplexe Abfragen: „Umdenken du musst!“
(Facebook, 2012)
70. #WISSENTEILEN
GraphQL Idee:
• Beliebige Abfragen via Objekt-Graph
auf dem ich navigieren kann.
• Lieferung des Abfrage-Results in einem
einzigen Round-Trip.
Komplexe Abfragen: „Umdenken du musst!“
77. #WISSENTEILEN
Komplexe Abfragen mit GraphQL
Wie alt ist Luke und welche
Haarfarbe hat er?
Mit welchem “Spruch“ wurden
die Filme eröffnet in denen er
mitgespielt hat?
Und wie teuer waren
überhaupt die Schiffe auf
denen er gefahren ist?
86. #WISSENTEILEN
Woher weiß das Backend was ich will?
• API Schema als gemeinsame Basis
• Query als Anfrage vom Client
• Step 1: parse (Query into an abstract syntax tree)*
• Step 2: validate (against Schema)**
• Step 3: execute (Resolve Functions)
GraphQL und das Backend
(*syntaktisch korrekt , **semantisch korrekt)
87. #WISSENTEILEN
// A very simple GraphQL schema example
type Character {
name: String! // non nullable
appearsIn: [Episode]! // array of ..., non nullable
}
type Starship {
id: ID! // unique ID
name: String!
length(unit: LengthUnit = METER): Float // parameter
}
GraphQL und das Backend
90. #WISSENTEILEN
Der GraphQL Server
• Query Parser
• Data Fetcher
• Data Aggregator
• Chaching von Result Graphs
• Aktuallisierung von Result Graphs
GraphQL und das Backend
91. #WISSENTEILEN
Muss ich das alles selber bauen?
• Nein! Es gibt ...
• Clients, Server, DB, Libraries, Tools ...
für Java, JavaScript, Python, Ruby, PHP, C/C++, GO, Scala, .Net,
SQL, ...
> http://graphql.org
> https://github.com/chentsulin/awesome-graphql
GraphQL und das Backend
92. #WISSENTEILEN
Cool, ist das wirklich alles so einfach?
• relative neue Technologie (im Fluss)
• Chaching?
• Dupletten?
• Information Hiding?
• Versionierung? (vs. deprecated)
GraphQL und Ich