web apis jenseits von rest & request/response

132
Web APIs Jenseits von REST & Request/Response Lars Röwekamp CIO New Technologies @mobileLarson @_openknowledge #WISSENTEILEN

Upload: open-knowledge-gmbh

Post on 16-Apr-2017

466 views

Category:

Software


1 download

TRANSCRIPT

Web APIs Jenseits von REST & Request/Response

Lars RöwekampCIO New Technologies

@mobileLarson@_openknowledge

#WISSENTEILEN

Branchenneutrale Softwareentwicklung und IT-Beratung

ÜBER OPEN KNOWLEDGE

#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

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

#WISSENTEILEN

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)

Das kleine REST 1x1

#WISSENTEILEN

HATEOAS? Pro Tipp: ... WAIT!

• What the heck is Hateoas?

REST & Evolution

#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

#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 & HateoasEntrypoint:

/orders

#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

demo$ rest 1x1demo$ |

#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

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

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

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)

#WISSENTEILEN

demo$ reqldemo$ |

#WISSENTEILEN

GraphQL

#WISSENTEILEN

GraphQL

#WISSENTEILEN

GraphQL

GraphQL

#WISSENTEILEN

Wer genau ist eigentlich dieser „Luke“?

• GET .../people/1

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)

#WISSENTEILEN

GraphQL

Umdenken du musst!

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.

#WISSENTEILEN

GraphQL

#WISSENTEILEN

GraphQL

#WISSENTEILEN

GraphQL

GraphQL

#WISSENTEILEN

GraphQL Charakteristika

• hierarchicial• product centric• strongly typed & instrospective• client specific queries• application-layer protokol

#WISSENTEILEN

GraphQL

Fragen, was du willst,du musst!

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

GraphQL

#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

}}

}

#WISSENTEILEN

demo$ graphQLdemo$ |

#WISSENTEILEN

GraphiQL

#WISSENTEILEN

GraphiQL

(http://graphql-swapi.parseapp.com)

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

}

#WISSENTEILEN

GraphQL

Aggregation?

Aggregation?

Aggregation?

#WISSENTEILEN

GraphQL

Aggregation!

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)

Async

Sync

vs.

#WISSENTEILEN

Sync vs. Async

A: POST /orders <order …>

B: ...

#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

A: POST /orders <order …>

B: Berlin, we have a problem (?)

#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

#WISSENTEILEN

Sync vs. Async

#WISSENTEILEN

Sync vs. Async

#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

#WISSENTEILEN

Sync vs. Async

#WISSENTEILEN

Sync vs. Async

#WISSENTEILEN

Sync vs. Async

#WISSENTEILEN

Sync vs. Async

#WISSENTEILEN

Sync vs. Async

#WISSENTEILEN

Sync vs. Async

#WISSENTEILEN

demo$ messagingdemo$ |

#WISSENTEILEN

Sync vs. Async

#WISSENTEILEN

Sync vs. Async

#WISSENTEILEN

Sync vs. Async

#WISSENTEILEN

Sync vs. Async

#WISSENTEILEN

Sync vs. Async

#WISSENTEILEN

Sync vs. Async

BTW: still sync!

#WISSENTEILEN

Sync vs. Async

#WISSENTEILEN

Sync vs. Async

#WISSENTEILEN

Sync vs. Async

#WISSENTEILEN

Sync vs. Async

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

#WISSENTEILEN

Web Sockets

#WISSENTEILEN

Web Sockets

#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

#WISSENTEILEN

Web Sockets

#WISSENTEILEN

Web Sockets

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)

#WISSENTEILEN

demo$ websocketsdemo$ |

#WISSENTEILEN

Sync vs. Async

WebSocket!

#WISSENTEILEN

#WISSENTEILEN

If you use REST,use it at it‘s best.

FAZIT

#WISSENTEILEN

It‘s not REST if it‘s not pragmatic.

FAZIT

#WISSENTEILEN

If it‘s not pragmaticdon‘t use REST!

FAZIT

#WISSENTEILEN

#WISSENTEILEN

? # !

LARS RÖWEKAMPCIO NEW TECHNOLOGIES

[email protected]+49 (0) 441 4082 – 0

@mobileLarson@_openknowledge

OFFENKUNDIGGUT

KOTAKT

#WISSENTEILEN

#1: © mantinov– shutterstock.com#16: © Ollyy – shutterstock.com#40: © pathdoc – shutterstock.com#52: TODO: iStock_000059091620_Large.jpg

#119: © marekuliasz– shutterstock.com

#4, #23, #25, #29: #44: pixabay.com

Icons in this presentation designed by “Freepik”,

BILDNACHWEISE

#WISSENTEILEN