web apis jenseits von rest & request/response
TRANSCRIPT
Web APIs Jenseits von REST & Request/Response
Lars RöwekampCIO New Technologies
@mobileLarson@_openknowledge
#WISSENTEILEN
Lars Röwekamp (a.k.a. @mobileLarson)
ÜBER MICH
LR
#WISSENTEILEN
Wer bin ich - und wen ja, wie viele?
• CIO New Technologies • Enterprise & Mobile • Author, Speaker, Coach & Mentor
• Snowboard & MTB Enthusiast• mehrfacher Vater, einfacher Ehemann
Das kleine REST 1x1
#WISSENTEILEN
REpresentational State Transfer is about ...
• Architectural Design Style• Client-Server• Stateless• Cache• Uniform Interface• Layered System
Das kleine REST 1x1
#WISSENTEILEN
REpresentational State Transfer
• Identifikation durch URL• Manipulation durch Representation• Selbstbeschreibende Messages• Hypermedia
/orders/123JSON/XML
GET, POST, PUT, DELETEMedia Types, Headers, ...References
Das kleine REST 1x1
#WISSENTEILEN
.../orders/ ... /orders/123
ListeallerBestellungen einzelne Bestellung123
erzeugeneuen Bestellung ERROR
ändere„Liste“vonBestellung
ändereBestellung 123sonstERROR
löschealleBestellungen löscheBestellung 123
Nomen
GET
POST
PUT
DELETE
Single Item URIList URI
Plural
Das kleine REST 1x1
#WISSENTEILEN
Golden rules of REST
• „We only need two URLs“ • „Verbs are bad, nouns are good“• „Plurals are even better“• „The web is your friend“• „There is always a root (associations)“• „There is always a parameter (complex stuff)“
Das kleine REST 1x1
#WISSENTEILEN
„There is always a root“
• GET /orders/123/ingredients• GET /orders/123/ingredients/456• GET /orders/123/ingredients/milk• PUT /orders/123/ingredients/milk• POST /orders/123/ingredients/milk• DELETE /orders/123/ingredients/milk
Das kleine REST 1x1
#WISSENTEILEN
„There is always a parameter“
• Path für Ressource Identifier • Query für Abfrageparameter, Filter, etc. • Body für Ressource-spezifische Logik • Header für globale, plattformweite Parameter
Das kleine REST 1x1
#WISSENTEILEN
Headers? Pro Tipp: Use them!
• Version-Header• Location-Header• Accept-Header• Content-Type• Link-Header• X-Custom-Header (Override Method, Limit, ...)
Das kleine REST 1x1
#WISSENTEILEN
Status Codes? Pro Tipp: Use them!
• 1xx: Hold on ...• 2xx: Here you go!• 3xx: Go away!• 4xx: You f#!?ed up!• 5xx: I f#!?ed up!
Das kleine REST 1x1
#WISSENTEILEN
Status Codes? Pro Tipp: Use them!
• 1xx: Hold on ...• 2xx: Here you go!• 3xx: Go away!• 4xx: You f#!?ed up!• 5xx: I f#!?ed up!
(http://restlet.com/http-status-codes-map)
#WISSENTEILEN
REST & Hateoas
„If the engine of application state (andhence the API) is not driven by hypertext, then it cannot be RESTful and cannot be a REST API.“
RoyFielding
#WISSENTEILEN
REST & Hateoas
„A REST API should be entered with noprior knowledge beyond the initial URI ... From that point on, all application statetransitions must be driven by the clientselection of server-provides choices ...“
RoyFielding
#WISSENTEILEN
REST & Hateoas// Response with link header for HYPERMEDIA navigation// after calling „POST .../orders/ <order ... />“
HTTP/1.1. 201 Created[various other headers]
Link: <.../orders/1234>; rel=„cancel“<.../orders/1234>; rel=„update“, <.../orders/1234>; rel=„delete“,<.../payment/1234>; rel=„pay“
#WISSENTEILEN
REST & Hateoas// Response with link header for HYPERMEDIA navigation// after calling „GET .../orders?page=10“
HTTP/1.1. 206 Partial Content[various other headers]
Link: <.../orders?page=1>; rel=„first“<.../orders?page=9>; rel=„next“, <.../orders?page=11>; rel=„prev“,<.../orders?page=17>; rel=„last“
#WISSENTEILEN
REST & Hateoas// Response with link header for HYPERMEDIA navigation// after calling „GET .../orders?page=10“
HTTP/1.1. 206 Partial Content[various other headers]
Link: <.../orders?page=1>; rel=„first“<.../orders?page=9>; rel=„next“, <.../orders?page=11>; rel=„prev“,<.../orders?page=17>; rel=„last“
Wait, does thismake sense?
REST & Pagination
#WISSENTEILEN
Wie navigiere ich durch Ressourcen?
• Path Parameter?• Query Parameter?
• Client Side Calculation?• Server Side Calculation?
#WISSENTEILEN
REST & Pagination// List page 4 of offers
// Is page a query parameter?GET /offers?page=4 HTTP/1.1
// Or is page a „virtual“ resource?GET /offers/page/4 HTTP/1.1
BTW: what does„page 4“ mean?
#WISSENTEILEN
REST & Pagination// List next 5 offers starting from offer 10
// Or is page x a result of offset and limit?GET /offers?offset=10&limit=5 HTTP/1.1
// Response with success code and link header for// navigation purposeHTTP/1.1. 206 Partial contentLink: <.../orders?offset=0&limit=5>; rel=„first“
<.../orders?offset=5&limit=5>; rel=„prev“, <.../orders?offset=15&limit=5>; rel=„next“,<.../orders?offset=40&limit=2>; rel=„last“
BTW: What‘s aboutfiltering, sorting, ....
REST & Queries
#WISSENTEILEN
Was ist eigentlich mit ...
• komplex(er)en Anfragen?• eingeschränkten Rückgabeobjekten?• (alternativen) Sortierungen?• alternativen Rückgabeformat?
Und wie sieht es mit „allgemeiner“ Suche aus?
#WISSENTEILEN
REST & Queries// FILTERING: List of paid orders (2015-12-20)
// Common StyleGET /orders?date=20151220&status=payed HTTP/1.1[various other headers]
#WISSENTEILEN
REST & Queries// FILTERING: Details of order 3: product, date & status
// Facebook StyleGET /orders/3?fields=product,date,status HTTP/1.1[various other headers]
GET /orders/3?fields=item.product,date,status HTTP/1.1[various other headers]
// LinkedIn StyleGET /orders/3:(product, date, status) HTTP/1.1[various other headers]
#WISSENTEILEN
REST & Queries// FILTERING: Details of order 3
// without date, statusGET /orders/3?exclude=date,status HTTP/1.1[various other headers]
// predefined payload (compact = product, date, status)GET /orders/3?style=compact HTTP/1.1[various other headers]
BTW: what does„compact“ mean?
#WISSENTEILEN
REST & Queries// FILTERING: Details of order 3
// using PREFER HEADER for response payload definitionGET /orders/3 HTTP/1.1Content-Type: application/jsonPrefer: return=compact-format
HTTP 1.1 200 OKContent-Type: application/json; charset=utf-8Preference-Applied: return=compact
#WISSENTEILEN
REST & Queries// SORTING: List of 10 orders sorted by date and item
// SQL StyleGET /orders?sort=date+DESC,item+ASC&count=10 HTTP/1.1
// Sort and asc/desc combination, ascending as defaultGET /orders?sort=date,item&desc=date&count=10 HTTP/1.1
// use prefix „-“ for descending, ascending as defaultGET /orders?sort=-date,item&count=10 HTTP/1.1
#WISSENTEILEN
REST & Queries// FORMATS: List of orders in alternative format xml
// Google style GET /orders?alt=xml HTTP/1.1
// Foursquare style (v1)GET /orders.xml HTTP/1.1
// Digg style GET /orders?type=xml HTTP/1.1Accept: application/xml
#WISSENTEILEN
REST & Queries// FULL TEXT SEARCH: Fulltext search for „coffee“
// Global styleGET /search?q=coffee HTTP/1.1
// Scoped styleGET /orders/search?q=coffee HTTP/1.1GET /orders?q=coffee HTTP/1.1
// Formatted styleGET /search.xml?q=coffee HTTP/1.1GET /orders/search.xml?q=coffee HTTP/1.1
#WISSENTEILEN
REST & Queries// ADVANCED SEARCH: „coffee with milk for 2 €“
// Query for ... GET /orders?type=coffee&ingredient=milk&price=2 HTTP/1.1
BTW: AND or OR orAND/OR?
#WISSENTEILEN
REST & Queries// ADVANCED SEARCH: „coffee WITH milk for LESS THAN 2 €“
// Query for ... GET /orders?query=type=coffee+ingredient=milk+price<=2
Build your own„Query Language“?
RQL
#WISSENTEILEN
Resource Query Language
• Object-Style Query Language• FIQL Superset (erweiterbar)
• Spezifikation & JS Parser (Client & Server)• JS Array, SQL, MongoDB, Elastic Search• Java Parser + JPA Criteria Builder
#WISSENTEILEN
RQL// ADVANCED SEARCH: „coffee WITH milk for LESS THAN 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==coff*;(ingredients==MILK,price=lt=2)
GraphQL
#WISSENTEILEN
Wer genau ist eigentlich dieser „Luke“ und in welchen Filmen hat er mitgespielt?
• GET .../film/1• GET .../film/2• GET .../film/3
• GET .../people/1/films (if offered via Endpoint)
GraphQL
#WISSENTEILEN
Wer genau ist eigentlich dieser „Luke“ und in welchen Filmen hat er mitgespielt und auf welchen Schiffen ist er gefahren?
• GET .../starship/12• GET .../starship/22
• GET .../peolple/1/starship (if offered)
GraphQL
#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 Schiffe auf denen er gefahren ist?
• GET .../#1?F#CKING/detail (n+1 problem?)• GET .../#1?F#CKING/all (job problem)
GraphQL
#WISSENTEILEN
GraphQL Motivation
„ We see a conflict between the desire to loadall information in a single round trip whilekeeping REST resources well isolated.”
(Facebook,2012)
GraphQL
#WISSENTEILEN
GraphQL Idee
• Beliebige Abfragen via Objekt-Graph auf dem ich navigieren kann.
• Lieferung des Abfrage-Results in einem einzigen Round-Trip.
GraphQL
#WISSENTEILEN
GraphQL Charakteristika
• hierarchicial• product centric• strongly typed & instrospective• client specific queries• application-layer protokol
GraphQL
#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 Schiffe auf denen er gefahren ist?
#WISSENTEILEN
GraphQLWie 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?
#WISSENTEILEN
GraphQLWie 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?
#WISSENTEILEN
GraphQLWie 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?
{person(name:„Luke“) {
haircolor, age
films {name,openiningCrawl
}
starships {name, price
}}
}
#WISSENTEILEN
GraphQLWie 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?
{person(name:„Luke“) {
haircolor, age
films {name,openiningCrawl
}
starships {name, price
}}
}
#WISSENTEILEN
GraphQLWie 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?
{person(name:„Luke“) {
haircolor, age
films {name,openiningCrawl
}
starships {name, price
}}
}
#WISSENTEILEN
GraphQLWie 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?
{person(name=„Luke“) {
haircolor, age
films {name,openiningCrawl
}
starships {name, price
}}
}
#WISSENTEILEN
GraphQLWie 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?
{person(name:„Luke“) {
haircolor, age
films {name,openiningCrawl
}
starships {name, price
}}
}
#WISSENTEILEN
GraphQLWie 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?
{person(name:„Luke“) {
haircolor, age
films {name,openiningCrawl
}
starships {name, price
}}
}
#WISSENTEILEN
GraphQLWie 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?
{person(name:„Luke“) {
haircolor, age
films {name,openiningCrawl
}
starships {name, price
}}
}
#WISSENTEILEN
GraphQLWie 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?
{person(name:„Luke“) {
haircolor, age
films {name,openiningCrawl
}
starships {name, price
}}
}
#WISSENTEILEN
GraphQLWie 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?
{person(name:„Luke“) {
haircolor, age
films {name,openiningCrawl
}
starships {name, price
}}
}
#WISSENTEILEN
GraphQLWie 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?
{person(name:„Luke“) {
haircolor, age
films {name,openiningCrawl
}
starships {name, price
}}
}
#WISSENTEILEN
GraphQLWie 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?
{person(name:„Luke“) {
haircolor, age
films {name,openiningCrawl
}
starships {name, price
}}
}
GraphQL
#WISSENTEILEN
Woher weiß das Backend was ich will?
• API Schema als gemeinsame Basis• Query als Anfrage vom Client
• Step 1: parse (Query into AST)• Step 2: validate (against Schema)• Step 3: execute (Resolve Functions)
#WISSENTEILEN
GraphQL// A very simple GraphQL schema example
type Character {name: String! // non nullableappearsIn: [Episode]! // array of ..., non nullable
}
type Starship {id: ID! // unique ID name: String!length(unit: LengthUnit = METER): Float // parameter
}
GraphQL
#WISSENTEILEN
GraphQL Server
• Query Parser• Data Fetcher• Data Aggregator
• Caching von Result Graphs• Aktualisierung von Result Graphs
GraphQL
#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
#WISSENTEILEN
Ist das wirklich so einfach?
• relative neue Technologie (im Fluss)
• Chaching?• Dupletten?• Information Hiding?• Versionierung (vs. deprecated)
#WISSENTEILEN
Sync vs. Async
B: OK 201 <order 1234 …<link „status“ … /><link „update“ … /><link „cancel“ … /><link „pay“ … />
/>
A: POST /orders <order …>
#WISSENTEILEN
Sync vs. Async
REST und ...
• Verbindungsproblem?• Bearbeitungsfehler?
• Callwiederholen?• Seiteneffekte!
• HTTPStatusCodes• ErrorPayload
#WISSENTEILEN
Sync vs. Async
REST und ...
• Fire &Forget?• Async Communication
• PasstnichtsorichtiginsREST-Konzept,oder?
Sync vs. Async
#WISSENTEILEN
Asyn Kommunikation
• via Messaging und Events• lose Kopplung durch Queues & Topics
oder durch Event Observer • ein Sender, 0 is N Receiver
• garantierte Auslieferung möglich• garantierte Auslieferung erzeugt Overhead
#WISSENTEILEN
Sync vs. Async
Messagingund ...
• Senderprobleme?• FalschesFormat
• Retry durchSender• Reliable Messages(ACK)• evtl.Duplicate
#WISSENTEILEN
Sync vs. Async
Messagingund ...
• Syncrone Kommunikation?
• 2xAsync =Sync ;-)• Correlation ID• Latenzbeachten
Web Sockets
#WISSENTEILEN
Web Sockets 1x1
• Paradigmenwechsel in der Kommunikation• Abkehr vom klassischen Request/Response
• Client meldet sich am Server an• Full duplex „real time“ Kommunikation• Session kann durch beide beendet werden
#WISSENTEILEN
Web Sockets
GET /chat HTTP/1.1
Host: server.example.comUpgrade: websocketConnection: UpgradeSec-WebSocket-Key: ...Origin: http://example.comSec-WebSocket-Protocol: chat, ...Sec-WebSocket-Version: 13
HTTP/1.1 101 Switching Protocols
Upgrade: websocketConnection: UpgradeSec-WebSocket-Accept: ...
Web Sockets
#WISSENTEILEN
WebSocket „Alternativen“
• Polling (e.g. via Ajax)• Long Polling• Piggy Back
Web Sockets
#WISSENTEILEN
Can i use Web Sockets ... (Server Side)
• Java EE 7• Spring
• Apache ActiveMQ, Caucho Resin, Jetty, Netty, vert.x, jWebsocket
and many more ...(see alsohttps://dzone.com/asset/download/253)
LARS RÖWEKAMPCIO NEW TECHNOLOGIES
[email protected]+49 (0) 441 4082 – 0
@mobileLarson@_openknowledge
OFFENKUNDIGGUT
KOTAKT
#WISSENTEILEN