SlideShare ist ein Scribd-Unternehmen logo
#WISSENTEILEN
@_openKnowledge
API-First
Design mit
Web-API Design
mit Java
BRANCHENNEUTRALE SOFTWAREENTWICKLUNG UND IT-BERATUNG
ÜBER OPEN KNOWLEDGE
ÜBER UNS
Wer bin ich - und wenn ja, wie viele?
• Enterprise Architect
• Enterprise & mehr
• Autor, Speaker, Berater, Coach
• Tauch & Ski Enthusiast
• Grillmeister & Hobbygärtner ;)
STEPHAN MÜLLER
SM
#WISSENTEILEN
Definition / Abgrenzung
API
• Schnittstelle für den Zugang zu Daten & Operationen einer
Anwendung oder Gruppe von Anwendungen
Web-API
• bietet einen oder mehrere Endpunkte für Web-Clients
• setzt typischerweise auf Request-Response Kommunikation
• tauscht Daten meist über JSON/XML aus
#WISSENTEILEN
Definition / Abgrenzung
Wann setze ich Web-APIs ein?
• als Schnittstelle für beliebige Clients (Public API)
nicht nur für Web, auch für Desktop-Anwendung & Mobil Apps
• als Schnittstelle zur Anbindung von Kunden oder Partnern
• Kommunikation innerhalb eines verteilten Systems
z.B. Microservices-Architektur
#WISSENTEILEN
Definition / Abgrenzung
Und welche Web-APIs gibt es nun ...?
• REST – Architekturstil definiert von Roy Fielding
Ausnutzung „aller“ HTTP Methoden & Hypermedia
• GraphQL – von Facebook als Alternative zu REST entwickelte
Query Language
• Server-Sent Events – W3C Standard für Push-Notifications
vom Server nach initialem Verbindungsaufbau durch Client
• WebSocket – W3C Standard für Full-Duplex Kommunikation
über TCP
#WISSENTEILEN
APIbucks
... ordering Coffee the digital way
#WISSENTEILEN
„Order 123 for
‚Larissa‘.“
„And here‘s the
receipt.“
„Here‘s 5$.“
„What‘s the
status of ‚123‘?“„Still preparing.“
„Now its ready.“
Web-API Design by Example
{?} „Coffee, latte,
large, to-go,
semi, double
shot, please.“
#WISSENTEILEN
order a coffee
customize
pay
check status
add to queue
deliver
Web-API Design by Example
{?}
#WISSENTEILEN
place an ORDER (UC-01)
customize the ORDER (UC-02)
pay for ORDER (UC-03)
check status of ORDER (UC-04)
add ORDER
to queue
deliver ORDER
Web-API Design by Example
{?}
#WISSENTEILEN
Was brauchen wir zur Umsetzung?
• Repräsentation der Order (JSON, XML, ...)
• Kommunikation zwischen Client & Service (HTTP)
• den Service selbst als Ressource (URI)
• und … (z.B. custom Header)
{?}
Web-API Design by Example
#WISSENTEILEN
Was brauchen wir NOCH zur Umsetzung?
• Notifications (Kaffee ist fertig)
• Error Handling (Sorry, die Bohnen sind alle)
• Transactions (Order entgegen nehmen, fertigen, liefern)
• Scalability (es kommen viele, viele Orders)
• Documentation (Ich möchte gerne bestellen, aber wie)
• Security (jeder soll nur seine Order ändern dürfen)
{?}
Web-API Design by Example
Caching
Rate Limiting
Swagger / OAS
JWT
Polling, Long-Polling,
SSE, WebSockets?
#WISSENTEILEN
Repräsentation der Order
• ASCII Encoded (JSON, XML, Custom)
• JSON == Native Web Format
• Developer/IDE friendly, breiter Language/Framework Support
• Binary Formats (Protocol Buffers, Apache Avro, Apache Thrift)
• effizient, klein & schnell*
• aus IDL Syntax wird Code generiert
• IoT (Rechenkapazität) & Finance (viele Transaktionen)
{?}
Web-API Design by Example
#WISSENTEILEN
Web-API Design by Example
Repräsentation der Order
• POS Format == Plain Object Serialization
• Custom Format
• JSend (super simple Application Level Protocol)
• Json:api (more complex Application Level Protocol)
• OData (OASIS Data JSON Format)
• HAL (Hypertext Application Language)
{?}
#WISSENTEILEN
// Payload POS (Plain Object Serialization) Format
GET /orders/1234 HTTP/1.1
Accept: application/json
// Order status
HTTP/1.1. 200 Ok
Content-Type: application/json
{
"id" : "4711"
"item" : { ... },
"location" : "take-away"
"price" : "2.25"
}
APIbucks
#WISSENTEILEN
// Payload JSend Data Format
GET /orders/1234 HTTP/1.1
Accept: application/json
// Order status
HTTP/1.1. 200 Ok
Content-Type: application/json
{
"status": <success|fail|error> String
"data": <single|list of> JSON (success or fail only)
"message": <error message> String (error only, opt.)
"code": <numeric error code> String (error only, opt.)
}
APIbucks
#WISSENTEILEN
// Payload OData Data Access Protocol
{
"@odata.context":
"http://mydomain.com/OrderService/$metadata#Orders",
"value": [
{
"@odata.etag": "ABCDE4711",
"Name": "Latte Machiato",
"Size": "XL",
},
{ "@odata.etag": "AXYZ0815", … }
]
}
APIbucks
#WISSENTEILEN
Notifications über Request-Response
• Request-Reponse vs. Server Push ⚡
• Polling
• check status … check status … check status …
• Long-Polling
• Verbindung bleibt bestehen bis neue Daten vorliegen
• anschließend erneute Anfrage
{?}
Web-API Design by Example
#WISSENTEILEN
// JAX-RS Async Long-Polling Example
@GET
@Path("/{id}")
public void getOrder(@PathParam("id") Long orderId,
@Suspended AsyncResponse asyncResponse) {
LOG.info("Get updates for order with id {}", orderId);
// store asynchronous response in ConcurrentMap
store.addResponse(orderId, asyncResponse);
}
APIbucks
#WISSENTEILEN
// JAX-RS Async Long-Polling Example
@PUT
@Path("/{id}")
public Response updateOrder(@PathParam("id") Long orderId,
ModifiedOrderer modifiedOrder) {
...
Order updatedOrder = repository.update(order);
store.getWaitingResponses(orderId)
.forEach(ar -> ar.resume(new OrderDto(updatedOrder)));
return Response.status(Status.NO_CONTENT).build();
}
APIbucks
#WISSENTEILEN
Notifications über serverseite Ereignisse
• Paradigmenwechsel in der Kommunikation
• Abkehr vom klassischen Request/Response
• Server-sent Events
• Senden von UTF-8 Daten vom Server zum Client (Server-Push)
• WebSockets
• Full-Duplex Real-Time Kommunikation (nur eine Verbindung)
{?}
Web-API Design by Example
#WISSENTEILEN
// SSE Async Servlet Example
@WebServlet(urlPatterns="/sse/orders", asyncSupported=true)
public class OrderSseServlet extends HttpServlet {
@Inject
private AsyncContextsStore store;
@Override
protected void doGet(...)
throws ServletException, IOException {
...
store.addContext(context);
}
}
APIbucks
#WISSENTEILEN
// SSE Async Servlet Example
public void observeOrderEvent(@Observes Order order) {
try {
String data = getData(order);
AsyncContent context = store.getContexts(username)
PrintWriter writer = context.getResponse().getWriter();
writer.append("n")
.append("event: status-changen")
.append("id:" + UUID.randomUUID() + "n")
.append("retry: 30000n")
.append("data:" + data + "nn")
.flush();
} catch (IOException e) { ... }
}
APIbucks
#WISSENTEILEN
// WebSocket Example
@ServerEndpoint(value = "/websocket/orders", encoders = …)
public class OrderNotificationEndpoint {
@Inject
private WebsocketSessionStore store;
@OnOpen
public void onOpen(...) { store.addSession(session); }
@OnClose
public void onClose(...) { store.removeSession(session); }
}
APIbucks
#WISSENTEILEN
// WebSocket Example
public void onOrderEvent(@Observes Order order) {
try {
OrderDto orderDto = new OrderDto(order);
Session session = store.getSession(username)
session.getBasicRemote().sendObject(orderEvent);
} catch (EncodeException | IOException e) {
LOG.error(e.getMessage(), e);
}
}
APIbucks
#WISSENTEILEN
Error Handling
• Eine API Operation hat i.d.R. drei mögliche Ergebnisse
• Request wurde erfolgreich verarbeitet (Statuscode 2xx)
• Client hat einen ungültigen Request gesendet (Statuscode 4xx)
• Request hat zu technischem Fehler geführt (Statuscode 5xx)
• Auch ErrorPayloads haben ein definiertes Format und
einen sinnvollen Content-Type
{?}
Web-API Design by Example
#WISSENTEILEN
// Error Handling Example
POST /orders HTTP/1.1
[various headers]
HTTP/1.1 400 Bad Request
[various other headers]
[
{ "code" : "23"
"propertyPath": "item.size",
"message": "Size must not be null" },
]
APIbucks
#WISSENTEILEN
// Bean Validation Exception Mapper
@Provider
public class ValidationExceptionMapper implements
ExceptionMapper<ConstraintViolationException> {
@Override
public Response toResponse(...) {
List<...> errors = e.getConstraintViolations().stream()
.map(error -> new ValidationError(error))
.collect(Collectors.toList());
return Response.status(BAD_REQUEST)
.type("application/json")
.entity(errors).build();
}
APIbucks
#WISSENTEILEN
Scalability
• Caching (Cache-Control & ETAG Header)
• „The Web is your Friend“
• Revalidation with Conditional GET & PUT
• Rate Limiting (X-Rate-Limit-* Header)
• Begrenzung von Zugriffen auf eine API
• Schränkt missbräuchliche Datenzugriffe ein
• Realisierung via Proxy / API Gateway (oder im Service)
{?}
Web-API Design by Example
#WISSENTEILEN
// Caching with Cache-Control Header Example
GET /orders/1234
[various other headers]
HTTP/1.1 200 Ok
[various other headers]
Cache-Control: private, no-store, max-age=3600
„Only client side
caching. Valid for
3600 sec. Must not
be stored on disc.“
APIbucks
#WISSENTEILEN
// Caching with Cache-Control Header Example
@GET
@Path("/{id}")
public Response getProduct(Long productId) {
...
CacheControl cacheControl = new CacheControl();
cacheControl.setMaxAge(300);
cacheControl.setPrivate(true);
cacheControl.setNoStore(true);
return Response.status(Status.OK).entity(...)
.cacheControl(cacheControl)
.build();
}
APIbucks
#WISSENTEILEN
// Conditional GET Example
GET /orders/1234
[various other headers]
HTTP/1.1 200 Ok
[various other headers]
Cache-Control: private, no-store, max-age=3600
ETag: "1234567890987654321"
APIbucks
#WISSENTEILEN
// Conditional GET Example
@GET
@Path("/{id}")
public Response getProduct(Long productId) {
ResponseBuilder builder =
request.evaluatePreconditions(createEntityTag(...));
if (builder != null) {
return builder.cacheControl(createControl()).build();
}
return Response.status(Status.OK).entity(...)
.cacheControl(createControl())
.tag(tag)
.build();
}
APIbucks
#WISSENTEILEN
// Conditional GET Example
GET /orders/1234 HTTP/1.1
[various other headers]
If-None-Match: "1234567890987654321"
HTTP/1.1 304 Not Modified
[various other headers]
Cache-Control: private, no-store, max-age=3600
Modified since? No,
304 (Not Modified).
Yes, 200 (Ok) plus
Data.
APIbucks
#WISSENTEILEN
// Rate-Limit Filter Example
@GET
@Path("/{id}")
@Limited(rateLimit = 3, timeFrame = 10000)
public Response getOrder(Long orderId) {
...
return Response.status(Status.OK)
.entity(...)
.build();
}
APIbucks
#WISSENTEILEN
// Rate-Limit Filter Example
@Limited
@Provider
@Priority(Priorities.AUTHENTICATION)
public class RateLimitPerTimeFrameFilter
implements ContainerRequestFilter {
@Context
private ResourceInfo resourceInfo;
public void filter(...) throws IOException { ... }
}
APIbucks
#WISSENTEILEN
// Rate-Limit example - first request
GET /orders/1234
[various other headers]
HTTP/1.1 200 Ok
[various other headers]
X-Rate-Limit-Limit: 3
X-Rate-Limit-Remaining: 2
X-Rate-Limit-Reset: 9
APIbucks
#WISSENTEILEN
// Rate-Limit example – second request
GET /orders/1234
[various other headers]
HTTP/1.1 200 Ok
[various other headers]
X-Rate-Limit-Limit: 3
X-Rate-Limit-Remaining: 1
X-Rate-Limit-Reset: 8
APIbucks
#WISSENTEILEN
// Rate-Limit example – third request
GET /orders/1234
[various other headers]
HTTP/1.1 429 Too many requests
[various other headers]
X-Rate-Limit-Limit: 3
X-Rate-Limit-Remaining: 0
X-Rate-Limit-Reset: 7
APIbucks
#WISSENTEILEN
Security
• 401 „Unauthorized“ == „Unauthenticated“!
• 403 „Forbidden“ == „ Unauthorized“!
• Token-based Security mit JSON Web Token
• Role-based Access Control
{?}
Web-API Design by Example
#WISSENTEILEN
// Bearer header example (restricted to customer)
DELETE /orders/1234
[various other headers]
HTTP/1.1 401 Unauthorized
[various other headers]
APIbucks
#WISSENTEILEN
// Bearer header example (restricted to customer)
DELETE /orders/1234
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpX...
[various other headers]
HTTP/1.1 204 No content
[various other headers]
APIbucks
#WISSENTEILEN
// JWT Authorization Filter Example
DecodedJWT jwt = JWT
.require(Algorithm.RSA256((RSAKey)publicKey))
.withIssuer("http://my-sso-server/auth/")
.build
.verify(token);
String userId = jwt.getSubject();
String userName = jwt.getClaim("username").asString();
String email = jwt.getClaim("email").asString();
APIbucks
#WISSENTEILEN
// RolesAllowed Example
@POST
@RolesAllowed({"customer"})
public Response createOrder(NewOrder newOrder) {
...
OrderDTO createdOrder = ...
return Response.status(201)
.entity(createdOrder)
.build();
}
APIbucks
#WISSENTEILEN
Documentation
• OpenAPI Specification (OAS)
• fka Swagger RESTful API Documentation Specification
• (voll-) automatisierte Generierung (auch zur Laufzeit)
• Export in diverse Formate (e.g. AsciDoc, HTML, PDF)
• Unterstützung bei API First Design
{?}
Web-API Design by Example
#WISSENTEILEN
Swagger / Open API Specification (OAS)
Web-API Design by Example
Design mit Swagger Editor Build mit Swagger Codegen Dokumentiere mit Swagger-UI
#WISSENTEILEN
3rd Party Tools mit Swagger/OAS Unterstützung
• Teste API Operation mit Postman
• Teste Consumer-driven Contracts mit Pact
• Implementiere client-seitige Validierung auf Basis von JSON-
Schema
• Dokumentiere mit ReDoc & Asciidoc (z.B. PDF)
Web-API Design by Example
#WISSENTEILEN
// Swagger Annotations Example (API Operation & Responses)
@POST
@ApiOperation(value = "Create a new order")
@ApiResponses(@ApiResponse(code = 201,
message = "Order created", response = OrderDto.class))
@Transactional
public Response createOrder(@ApiParam(value = "new order")
NewOrder newOrder) {
...
}
APIbucks
#WISSENTEILEN
// Swagger Bootstrap Servlet Example
@WebServlet(loadOnStartup = 1)
public class SwaggerBootstrap extends HttpServlet {
@Override
public void init(ServletConfig c)throws ServletException {
super.init(c);
BeanConfig beanConfig = new BeanConfig();
...
beanConfig.setBasePath(...); // API Base-Path
beanConfig.setResourcePackage(...);
beanConfig.setScan(true);
}
}
APIbucks
#WISSENTEILEN
<!-- download swagger-ui -->
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>swagger ui</id>
<phase>prepare-package</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.webjars.npm</groupId>
<artifactId>swagger-ui-dist</artifactId>
<version>${version.swagger-ui}</version>
</artifactItem>
</artifactItems>
<outputDirectory>${project.build.directory}/swagger-
ui</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<!-- add swagger-ui to artefact -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<webResources combine.children="append">
<resource>
<directory>${project.build.directory}/swagger-ui/META-
INF/resources/webjars/swagger-ui-dist/${version.swagger-
ui}</directory>
<excludes>
<exclude>index.html</exclude>
</excludes>
</resource>
</webResources>
</configuration>
</plugin>
APIbucks
Pro
Tipp
#WISSENTEILEN
APIbucks
... Design the APIbucks API
#WISSENTEILEN
#WISSENTEILEN
Was ist nun der beste Ansatz eine API zu entwickeln?
• API-First Design
• Geräteunabhängiger Softwareentwurf
• Erster Schritt: Entwurf & Dokumentation einer API
• Code-First
• Developers Choice J
{?}
Web-API Design by Example
#WISSENTEILEN
{A}1ST
#WISSENTEILEN
YOUR API IS THE
FIRST USER
INTERFACE OF
YOUR APPLICATION
#WISSENTEILEN
YOUR API COMES
FIRST, THEN THE
IMPLEMENTATION
#WISSENTEILEN
YOUR API IS
DESCRIBED (AND
MABY EVEN
SELF-DESCRIPTIVE)
#WISSENTEILEN
API-First Design Lifecyce!
#1 – Planen
#2 – Entwerfen & Validieren
#3 – Überarbeiten
#4 – Testen
#5 – Implementieren
#6 – Betreiben & Lernen (zurück zu #1)
Web-API Design by Example
{?}
#WISSENTEILEN
http://apistylebook.com/design/guidelines/
#WISSENTEILEN
K.I.S.S.a.k.a. „keep it stupid simple“
#WISSENTEILEN
Be pragmaticIts pragmatic if it works for you and your consumers
#WISSENTEILEN
„Das* API ist das
UI des Entwicklers.“
(*wer möchte, darf auch “die API“ sagen)
#WISSENTEILEN
„Entscheidend ist, dass das API aus
Sicht des Entwicklers konsistent und
leicht anwendbar ist.
#WISSENTEILEN
FRAGEN
? ? ?
Kontakt
STEPHAN MÜLLER
ENTERPRISE ARCHITECT
stephan.mueller@openknowledge.de
+49 (0)441 4082 – 0
@_openknowledge
OFFENKUNDIGGUT
#WISSENTEILEN
Bildnachweise
#01: © dzone.com
#46: © swagger.io
#50: © swagger.io
All other pictures inside this presentation orginate
from pixabay.com or were created by my own.
#WISSENTEILEN

Weitere ähnliche Inhalte

Ähnlich wie Web-API Design in Java

Web APIs jenseits von REST & Request/Response
Web APIs jenseits von REST & Request/ResponseWeb APIs jenseits von REST & Request/Response
Web APIs jenseits von REST & Request/Response
OPEN KNOWLEDGE GmbH
 
Web-API-Design in Java
Web-API-Design in JavaWeb-API-Design in Java
Web-API-Design in Java
OPEN KNOWLEDGE GmbH
 
Rufen Sie nicht an – wir rufen Sie an! | Server-sent Events und Web-Sockets i...
Rufen Sie nicht an – wir rufen Sie an! | Server-sent Events und Web-Sockets i...Rufen Sie nicht an – wir rufen Sie an! | Server-sent Events und Web-Sockets i...
Rufen Sie nicht an – wir rufen Sie an! | Server-sent Events und Web-Sockets i...
OPEN KNOWLEDGE GmbH
 
Herausforderung „Multi-Channel“-Architektur
Herausforderung „Multi-Channel“-ArchitekturHerausforderung „Multi-Channel“-Architektur
Herausforderung „Multi-Channel“-Architektur
OPEN KNOWLEDGE GmbH
 
Ajax hands on - Refactoring Google Suggest
Ajax hands on - Refactoring Google SuggestAjax hands on - Refactoring Google Suggest
Ajax hands on - Refactoring Google Suggest
Bastian Feder
 
Web APIs auf dem Prüfstand - Volle Kontrolle oder fertig mit den Azure Mobile...
Web APIs auf dem Prüfstand - Volle Kontrolle oder fertig mit den Azure Mobile...Web APIs auf dem Prüfstand - Volle Kontrolle oder fertig mit den Azure Mobile...
Web APIs auf dem Prüfstand - Volle Kontrolle oder fertig mit den Azure Mobile...
Peter Kirchner
 
Herausforderung „Multi-Channel Architecture”
Herausforderung „Multi-Channel Architecture”Herausforderung „Multi-Channel Architecture”
Herausforderung „Multi-Channel Architecture”
OPEN KNOWLEDGE GmbH
 
Wieviel client braucht das web
Wieviel client braucht das webWieviel client braucht das web
Wieviel client braucht das web
gedoplan
 
Wieviel Client braucht das Web?
Wieviel Client braucht das Web?Wieviel Client braucht das Web?
Wieviel Client braucht das Web?
gedoplan
 
Legacy WebApps mit AngularJS pimpen
Legacy WebApps mit AngularJS pimpenLegacy WebApps mit AngularJS pimpen
Legacy WebApps mit AngularJS pimpen
Philipp Burgmer
 
Mehrere Apps, ein Backend: Windows Azure Mobile Services in der Praxis
Mehrere Apps, ein Backend: Windows Azure Mobile Services in der PraxisMehrere Apps, ein Backend: Windows Azure Mobile Services in der Praxis
Mehrere Apps, ein Backend: Windows Azure Mobile Services in der Praxis
Jan Hentschel
 
Übersicht über Tubewarder | Template-basiertes Message Gateway
Übersicht über Tubewarder | Template-basiertes Message GatewayÜbersicht über Tubewarder | Template-basiertes Message Gateway
Übersicht über Tubewarder | Template-basiertes Message Gateway
weweave GbR
 
Api Platform: the ultimate API Platform
Api Platform: the ultimate API PlatformApi Platform: the ultimate API Platform
Api Platform: the ultimate API Platform
Stefan Adolf
 
Apple iOS - Webservices
Apple iOS - WebservicesApple iOS - Webservices
Apple iOS - Webservices
messeb
 
Creasoft-Akademie - Mobile Multiplattform Apps
Creasoft-Akademie - Mobile Multiplattform AppsCreasoft-Akademie - Mobile Multiplattform Apps
Creasoft-Akademie - Mobile Multiplattform Apps
Creasoft AG
 
Wozu Portlets – reichen HTML5 und Rest nicht aus für moderne Portale?
Wozu Portlets – reichen HTML5 und Rest nicht aus für moderne Portale?Wozu Portlets – reichen HTML5 und Rest nicht aus für moderne Portale?
Wozu Portlets – reichen HTML5 und Rest nicht aus für moderne Portale?
adesso AG
 
Cloud Native & Java EE: Freund oder Feind?
Cloud Native & Java EE: Freund oder Feind?Cloud Native & Java EE: Freund oder Feind?
Cloud Native & Java EE: Freund oder Feind?
QAware GmbH
 
Cloud Native und Java EE: Freund oder Feind?
Cloud Native und Java EE: Freund oder Feind?Cloud Native und Java EE: Freund oder Feind?
Cloud Native und Java EE: Freund oder Feind?
Josef Adersberger
 
Integration von Security-Checks in die CI-Pipeline
Integration von Security-Checks in die CI-PipelineIntegration von Security-Checks in die CI-Pipeline
Integration von Security-Checks in die CI-Pipeline
OPEN KNOWLEDGE GmbH
 

Ähnlich wie Web-API Design in Java (20)

Web APIs jenseits von REST & Request/Response
Web APIs jenseits von REST & Request/ResponseWeb APIs jenseits von REST & Request/Response
Web APIs jenseits von REST & Request/Response
 
Web-API-Design in Java
Web-API-Design in JavaWeb-API-Design in Java
Web-API-Design in Java
 
Rufen Sie nicht an – wir rufen Sie an! | Server-sent Events und Web-Sockets i...
Rufen Sie nicht an – wir rufen Sie an! | Server-sent Events und Web-Sockets i...Rufen Sie nicht an – wir rufen Sie an! | Server-sent Events und Web-Sockets i...
Rufen Sie nicht an – wir rufen Sie an! | Server-sent Events und Web-Sockets i...
 
Herausforderung „Multi-Channel“-Architektur
Herausforderung „Multi-Channel“-ArchitekturHerausforderung „Multi-Channel“-Architektur
Herausforderung „Multi-Channel“-Architektur
 
Ajax hands on - Refactoring Google Suggest
Ajax hands on - Refactoring Google SuggestAjax hands on - Refactoring Google Suggest
Ajax hands on - Refactoring Google Suggest
 
Web APIs auf dem Prüfstand - Volle Kontrolle oder fertig mit den Azure Mobile...
Web APIs auf dem Prüfstand - Volle Kontrolle oder fertig mit den Azure Mobile...Web APIs auf dem Prüfstand - Volle Kontrolle oder fertig mit den Azure Mobile...
Web APIs auf dem Prüfstand - Volle Kontrolle oder fertig mit den Azure Mobile...
 
Herausforderung „Multi-Channel Architecture”
Herausforderung „Multi-Channel Architecture”Herausforderung „Multi-Channel Architecture”
Herausforderung „Multi-Channel Architecture”
 
Wieviel client braucht das web
Wieviel client braucht das webWieviel client braucht das web
Wieviel client braucht das web
 
Wieviel Client braucht das Web?
Wieviel Client braucht das Web?Wieviel Client braucht das Web?
Wieviel Client braucht das Web?
 
Legacy WebApps mit AngularJS pimpen
Legacy WebApps mit AngularJS pimpenLegacy WebApps mit AngularJS pimpen
Legacy WebApps mit AngularJS pimpen
 
Mehrere Apps, ein Backend: Windows Azure Mobile Services in der Praxis
Mehrere Apps, ein Backend: Windows Azure Mobile Services in der PraxisMehrere Apps, ein Backend: Windows Azure Mobile Services in der Praxis
Mehrere Apps, ein Backend: Windows Azure Mobile Services in der Praxis
 
Übersicht über Tubewarder | Template-basiertes Message Gateway
Übersicht über Tubewarder | Template-basiertes Message GatewayÜbersicht über Tubewarder | Template-basiertes Message Gateway
Übersicht über Tubewarder | Template-basiertes Message Gateway
 
Api Platform: the ultimate API Platform
Api Platform: the ultimate API PlatformApi Platform: the ultimate API Platform
Api Platform: the ultimate API Platform
 
Apple iOS - Webservices
Apple iOS - WebservicesApple iOS - Webservices
Apple iOS - Webservices
 
Creasoft-Akademie - Mobile Multiplattform Apps
Creasoft-Akademie - Mobile Multiplattform AppsCreasoft-Akademie - Mobile Multiplattform Apps
Creasoft-Akademie - Mobile Multiplattform Apps
 
Wozu Portlets – reichen HTML5 und Rest nicht aus für moderne Portale?
Wozu Portlets – reichen HTML5 und Rest nicht aus für moderne Portale?Wozu Portlets – reichen HTML5 und Rest nicht aus für moderne Portale?
Wozu Portlets – reichen HTML5 und Rest nicht aus für moderne Portale?
 
Cloud Native & Java EE: Freund oder Feind?
Cloud Native & Java EE: Freund oder Feind?Cloud Native & Java EE: Freund oder Feind?
Cloud Native & Java EE: Freund oder Feind?
 
Cloud Native und Java EE: Freund oder Feind?
Cloud Native und Java EE: Freund oder Feind?Cloud Native und Java EE: Freund oder Feind?
Cloud Native und Java EE: Freund oder Feind?
 
GWT
GWTGWT
GWT
 
Integration von Security-Checks in die CI-Pipeline
Integration von Security-Checks in die CI-PipelineIntegration von Security-Checks in die CI-Pipeline
Integration von Security-Checks in die CI-Pipeline
 

Mehr von OPEN KNOWLEDGE GmbH

Warum der Computer "Nein" sagt - Mehr Nachvollziehbarkeit dank Explainable AI
Warum der Computer "Nein" sagt - Mehr Nachvollziehbarkeit dank Explainable AIWarum der Computer "Nein" sagt - Mehr Nachvollziehbarkeit dank Explainable AI
Warum der Computer "Nein" sagt - Mehr Nachvollziehbarkeit dank Explainable AI
OPEN KNOWLEDGE GmbH
 
Machine Learning? Ja gerne! Aber was und wie? Eine Kurzanleitung für den erfo...
Machine Learning? Ja gerne! Aber was und wie? Eine Kurzanleitung für den erfo...Machine Learning? Ja gerne! Aber was und wie? Eine Kurzanleitung für den erfo...
Machine Learning? Ja gerne! Aber was und wie? Eine Kurzanleitung für den erfo...
OPEN KNOWLEDGE GmbH
 
From Zero to still Zero: Die schönsten Fehler auf dem Weg in die Cloud
From Zero to still Zero: Die schönsten Fehler auf dem Weg in die CloudFrom Zero to still Zero: Die schönsten Fehler auf dem Weg in die Cloud
From Zero to still Zero: Die schönsten Fehler auf dem Weg in die Cloud
OPEN KNOWLEDGE GmbH
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)
OPEN KNOWLEDGE GmbH
 
FEHLENDE DATEN? (K)EIN PROBLEM!: Die Kunst der Data Imputation
FEHLENDE DATEN? (K)EIN PROBLEM!: Die Kunst der Data ImputationFEHLENDE DATEN? (K)EIN PROBLEM!: Die Kunst der Data Imputation
FEHLENDE DATEN? (K)EIN PROBLEM!: Die Kunst der Data Imputation
OPEN KNOWLEDGE GmbH
 
Nie wieder Log-Files!
Nie wieder Log-Files!Nie wieder Log-Files!
Nie wieder Log-Files!
OPEN KNOWLEDGE GmbH
 
Cloud-native and Enterprise Java? Hold my beer!
Cloud-native and Enterprise Java? Hold my beer!Cloud-native and Enterprise Java? Hold my beer!
Cloud-native and Enterprise Java? Hold my beer!
OPEN KNOWLEDGE GmbH
 
From Zero to still Zero: The most beautiful mistakes going into the cloud.
From Zero to still Zero: The most beautiful mistakes going into the cloud. From Zero to still Zero: The most beautiful mistakes going into the cloud.
From Zero to still Zero: The most beautiful mistakes going into the cloud.
OPEN KNOWLEDGE GmbH
 
API Expand Contract
API Expand ContractAPI Expand Contract
API Expand Contract
OPEN KNOWLEDGE GmbH
 
Ready for the Future: Jakarta EE in Zeiten von Cloud Native & Co
Ready for the Future: Jakarta EE in Zeiten von Cloud Native & CoReady for the Future: Jakarta EE in Zeiten von Cloud Native & Co
Ready for the Future: Jakarta EE in Zeiten von Cloud Native & Co
OPEN KNOWLEDGE GmbH
 
Shared Data in verteilten Architekturen
Shared Data in verteilten ArchitekturenShared Data in verteilten Architekturen
Shared Data in verteilten Architekturen
OPEN KNOWLEDGE GmbH
 
Machine Learning mit TensorFlow.js
Machine Learning mit TensorFlow.jsMachine Learning mit TensorFlow.js
Machine Learning mit TensorFlow.js
OPEN KNOWLEDGE GmbH
 
KI und Architektur
KI und ArchitekturKI und Architektur
KI und Architektur
OPEN KNOWLEDGE GmbH
 
It's not Rocket Science: Neuronale Netze
It's not Rocket Science: Neuronale NetzeIt's not Rocket Science: Neuronale Netze
It's not Rocket Science: Neuronale Netze
OPEN KNOWLEDGE GmbH
 
Shared Data in verteilten Systemen
Shared Data in verteilten SystemenShared Data in verteilten Systemen
Shared Data in verteilten Systemen
OPEN KNOWLEDGE GmbH
 
Business-Mehrwert durch KI
Business-Mehrwert durch KIBusiness-Mehrwert durch KI
Business-Mehrwert durch KI
OPEN KNOWLEDGE GmbH
 
Mehr Sicherheit durch Automatisierung
Mehr Sicherheit durch AutomatisierungMehr Sicherheit durch Automatisierung
Mehr Sicherheit durch Automatisierung
OPEN KNOWLEDGE GmbH
 
API-Design, Microarchitecture und Testing
API-Design, Microarchitecture und TestingAPI-Design, Microarchitecture und Testing
API-Design, Microarchitecture und Testing
OPEN KNOWLEDGE GmbH
 
Supersonic Java für die Cloud: Quarkus
Supersonic Java für die Cloud: QuarkusSupersonic Java für die Cloud: Quarkus
Supersonic Java für die Cloud: Quarkus
OPEN KNOWLEDGE GmbH
 
Hilfe, ich will meinen Monolithen zurück!
Hilfe, ich will meinen Monolithen zurück!Hilfe, ich will meinen Monolithen zurück!
Hilfe, ich will meinen Monolithen zurück!
OPEN KNOWLEDGE GmbH
 

Mehr von OPEN KNOWLEDGE GmbH (20)

Warum der Computer "Nein" sagt - Mehr Nachvollziehbarkeit dank Explainable AI
Warum der Computer "Nein" sagt - Mehr Nachvollziehbarkeit dank Explainable AIWarum der Computer "Nein" sagt - Mehr Nachvollziehbarkeit dank Explainable AI
Warum der Computer "Nein" sagt - Mehr Nachvollziehbarkeit dank Explainable AI
 
Machine Learning? Ja gerne! Aber was und wie? Eine Kurzanleitung für den erfo...
Machine Learning? Ja gerne! Aber was und wie? Eine Kurzanleitung für den erfo...Machine Learning? Ja gerne! Aber was und wie? Eine Kurzanleitung für den erfo...
Machine Learning? Ja gerne! Aber was und wie? Eine Kurzanleitung für den erfo...
 
From Zero to still Zero: Die schönsten Fehler auf dem Weg in die Cloud
From Zero to still Zero: Die schönsten Fehler auf dem Weg in die CloudFrom Zero to still Zero: Die schönsten Fehler auf dem Weg in die Cloud
From Zero to still Zero: Die schönsten Fehler auf dem Weg in die Cloud
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)
 
FEHLENDE DATEN? (K)EIN PROBLEM!: Die Kunst der Data Imputation
FEHLENDE DATEN? (K)EIN PROBLEM!: Die Kunst der Data ImputationFEHLENDE DATEN? (K)EIN PROBLEM!: Die Kunst der Data Imputation
FEHLENDE DATEN? (K)EIN PROBLEM!: Die Kunst der Data Imputation
 
Nie wieder Log-Files!
Nie wieder Log-Files!Nie wieder Log-Files!
Nie wieder Log-Files!
 
Cloud-native and Enterprise Java? Hold my beer!
Cloud-native and Enterprise Java? Hold my beer!Cloud-native and Enterprise Java? Hold my beer!
Cloud-native and Enterprise Java? Hold my beer!
 
From Zero to still Zero: The most beautiful mistakes going into the cloud.
From Zero to still Zero: The most beautiful mistakes going into the cloud. From Zero to still Zero: The most beautiful mistakes going into the cloud.
From Zero to still Zero: The most beautiful mistakes going into the cloud.
 
API Expand Contract
API Expand ContractAPI Expand Contract
API Expand Contract
 
Ready for the Future: Jakarta EE in Zeiten von Cloud Native & Co
Ready for the Future: Jakarta EE in Zeiten von Cloud Native & CoReady for the Future: Jakarta EE in Zeiten von Cloud Native & Co
Ready for the Future: Jakarta EE in Zeiten von Cloud Native & Co
 
Shared Data in verteilten Architekturen
Shared Data in verteilten ArchitekturenShared Data in verteilten Architekturen
Shared Data in verteilten Architekturen
 
Machine Learning mit TensorFlow.js
Machine Learning mit TensorFlow.jsMachine Learning mit TensorFlow.js
Machine Learning mit TensorFlow.js
 
KI und Architektur
KI und ArchitekturKI und Architektur
KI und Architektur
 
It's not Rocket Science: Neuronale Netze
It's not Rocket Science: Neuronale NetzeIt's not Rocket Science: Neuronale Netze
It's not Rocket Science: Neuronale Netze
 
Shared Data in verteilten Systemen
Shared Data in verteilten SystemenShared Data in verteilten Systemen
Shared Data in verteilten Systemen
 
Business-Mehrwert durch KI
Business-Mehrwert durch KIBusiness-Mehrwert durch KI
Business-Mehrwert durch KI
 
Mehr Sicherheit durch Automatisierung
Mehr Sicherheit durch AutomatisierungMehr Sicherheit durch Automatisierung
Mehr Sicherheit durch Automatisierung
 
API-Design, Microarchitecture und Testing
API-Design, Microarchitecture und TestingAPI-Design, Microarchitecture und Testing
API-Design, Microarchitecture und Testing
 
Supersonic Java für die Cloud: Quarkus
Supersonic Java für die Cloud: QuarkusSupersonic Java für die Cloud: Quarkus
Supersonic Java für die Cloud: Quarkus
 
Hilfe, ich will meinen Monolithen zurück!
Hilfe, ich will meinen Monolithen zurück!Hilfe, ich will meinen Monolithen zurück!
Hilfe, ich will meinen Monolithen zurück!
 

Web-API Design in Java

  • 2. BRANCHENNEUTRALE SOFTWAREENTWICKLUNG UND IT-BERATUNG ÜBER OPEN KNOWLEDGE
  • 3. ÜBER UNS Wer bin ich - und wenn ja, wie viele? • Enterprise Architect • Enterprise & mehr • Autor, Speaker, Berater, Coach • Tauch & Ski Enthusiast • Grillmeister & Hobbygärtner ;) STEPHAN MÜLLER SM
  • 4. #WISSENTEILEN Definition / Abgrenzung API • Schnittstelle für den Zugang zu Daten & Operationen einer Anwendung oder Gruppe von Anwendungen Web-API • bietet einen oder mehrere Endpunkte für Web-Clients • setzt typischerweise auf Request-Response Kommunikation • tauscht Daten meist über JSON/XML aus
  • 5. #WISSENTEILEN Definition / Abgrenzung Wann setze ich Web-APIs ein? • als Schnittstelle für beliebige Clients (Public API) nicht nur für Web, auch für Desktop-Anwendung & Mobil Apps • als Schnittstelle zur Anbindung von Kunden oder Partnern • Kommunikation innerhalb eines verteilten Systems z.B. Microservices-Architektur
  • 6. #WISSENTEILEN Definition / Abgrenzung Und welche Web-APIs gibt es nun ...? • REST – Architekturstil definiert von Roy Fielding Ausnutzung „aller“ HTTP Methoden & Hypermedia • GraphQL – von Facebook als Alternative zu REST entwickelte Query Language • Server-Sent Events – W3C Standard für Push-Notifications vom Server nach initialem Verbindungsaufbau durch Client • WebSocket – W3C Standard für Full-Duplex Kommunikation über TCP
  • 8. #WISSENTEILEN „Order 123 for ‚Larissa‘.“ „And here‘s the receipt.“ „Here‘s 5$.“ „What‘s the status of ‚123‘?“„Still preparing.“ „Now its ready.“ Web-API Design by Example {?} „Coffee, latte, large, to-go, semi, double shot, please.“
  • 9. #WISSENTEILEN order a coffee customize pay check status add to queue deliver Web-API Design by Example {?}
  • 10. #WISSENTEILEN place an ORDER (UC-01) customize the ORDER (UC-02) pay for ORDER (UC-03) check status of ORDER (UC-04) add ORDER to queue deliver ORDER Web-API Design by Example {?}
  • 11. #WISSENTEILEN Was brauchen wir zur Umsetzung? • Repräsentation der Order (JSON, XML, ...) • Kommunikation zwischen Client & Service (HTTP) • den Service selbst als Ressource (URI) • und … (z.B. custom Header) {?} Web-API Design by Example
  • 12. #WISSENTEILEN Was brauchen wir NOCH zur Umsetzung? • Notifications (Kaffee ist fertig) • Error Handling (Sorry, die Bohnen sind alle) • Transactions (Order entgegen nehmen, fertigen, liefern) • Scalability (es kommen viele, viele Orders) • Documentation (Ich möchte gerne bestellen, aber wie) • Security (jeder soll nur seine Order ändern dürfen) {?} Web-API Design by Example Caching Rate Limiting Swagger / OAS JWT Polling, Long-Polling, SSE, WebSockets?
  • 13. #WISSENTEILEN Repräsentation der Order • ASCII Encoded (JSON, XML, Custom) • JSON == Native Web Format • Developer/IDE friendly, breiter Language/Framework Support • Binary Formats (Protocol Buffers, Apache Avro, Apache Thrift) • effizient, klein & schnell* • aus IDL Syntax wird Code generiert • IoT (Rechenkapazität) & Finance (viele Transaktionen) {?} Web-API Design by Example
  • 14. #WISSENTEILEN Web-API Design by Example Repräsentation der Order • POS Format == Plain Object Serialization • Custom Format • JSend (super simple Application Level Protocol) • Json:api (more complex Application Level Protocol) • OData (OASIS Data JSON Format) • HAL (Hypertext Application Language) {?}
  • 15. #WISSENTEILEN // Payload POS (Plain Object Serialization) Format GET /orders/1234 HTTP/1.1 Accept: application/json // Order status HTTP/1.1. 200 Ok Content-Type: application/json { "id" : "4711" "item" : { ... }, "location" : "take-away" "price" : "2.25" } APIbucks
  • 16. #WISSENTEILEN // Payload JSend Data Format GET /orders/1234 HTTP/1.1 Accept: application/json // Order status HTTP/1.1. 200 Ok Content-Type: application/json { "status": <success|fail|error> String "data": <single|list of> JSON (success or fail only) "message": <error message> String (error only, opt.) "code": <numeric error code> String (error only, opt.) } APIbucks
  • 17. #WISSENTEILEN // Payload OData Data Access Protocol { "@odata.context": "http://mydomain.com/OrderService/$metadata#Orders", "value": [ { "@odata.etag": "ABCDE4711", "Name": "Latte Machiato", "Size": "XL", }, { "@odata.etag": "AXYZ0815", … } ] } APIbucks
  • 18. #WISSENTEILEN Notifications über Request-Response • Request-Reponse vs. Server Push ⚡ • Polling • check status … check status … check status … • Long-Polling • Verbindung bleibt bestehen bis neue Daten vorliegen • anschließend erneute Anfrage {?} Web-API Design by Example
  • 19. #WISSENTEILEN // JAX-RS Async Long-Polling Example @GET @Path("/{id}") public void getOrder(@PathParam("id") Long orderId, @Suspended AsyncResponse asyncResponse) { LOG.info("Get updates for order with id {}", orderId); // store asynchronous response in ConcurrentMap store.addResponse(orderId, asyncResponse); } APIbucks
  • 20. #WISSENTEILEN // JAX-RS Async Long-Polling Example @PUT @Path("/{id}") public Response updateOrder(@PathParam("id") Long orderId, ModifiedOrderer modifiedOrder) { ... Order updatedOrder = repository.update(order); store.getWaitingResponses(orderId) .forEach(ar -> ar.resume(new OrderDto(updatedOrder))); return Response.status(Status.NO_CONTENT).build(); } APIbucks
  • 21. #WISSENTEILEN Notifications über serverseite Ereignisse • Paradigmenwechsel in der Kommunikation • Abkehr vom klassischen Request/Response • Server-sent Events • Senden von UTF-8 Daten vom Server zum Client (Server-Push) • WebSockets • Full-Duplex Real-Time Kommunikation (nur eine Verbindung) {?} Web-API Design by Example
  • 22. #WISSENTEILEN // SSE Async Servlet Example @WebServlet(urlPatterns="/sse/orders", asyncSupported=true) public class OrderSseServlet extends HttpServlet { @Inject private AsyncContextsStore store; @Override protected void doGet(...) throws ServletException, IOException { ... store.addContext(context); } } APIbucks
  • 23. #WISSENTEILEN // SSE Async Servlet Example public void observeOrderEvent(@Observes Order order) { try { String data = getData(order); AsyncContent context = store.getContexts(username) PrintWriter writer = context.getResponse().getWriter(); writer.append("n") .append("event: status-changen") .append("id:" + UUID.randomUUID() + "n") .append("retry: 30000n") .append("data:" + data + "nn") .flush(); } catch (IOException e) { ... } } APIbucks
  • 24. #WISSENTEILEN // WebSocket Example @ServerEndpoint(value = "/websocket/orders", encoders = …) public class OrderNotificationEndpoint { @Inject private WebsocketSessionStore store; @OnOpen public void onOpen(...) { store.addSession(session); } @OnClose public void onClose(...) { store.removeSession(session); } } APIbucks
  • 25. #WISSENTEILEN // WebSocket Example public void onOrderEvent(@Observes Order order) { try { OrderDto orderDto = new OrderDto(order); Session session = store.getSession(username) session.getBasicRemote().sendObject(orderEvent); } catch (EncodeException | IOException e) { LOG.error(e.getMessage(), e); } } APIbucks
  • 26. #WISSENTEILEN Error Handling • Eine API Operation hat i.d.R. drei mögliche Ergebnisse • Request wurde erfolgreich verarbeitet (Statuscode 2xx) • Client hat einen ungültigen Request gesendet (Statuscode 4xx) • Request hat zu technischem Fehler geführt (Statuscode 5xx) • Auch ErrorPayloads haben ein definiertes Format und einen sinnvollen Content-Type {?} Web-API Design by Example
  • 27. #WISSENTEILEN // Error Handling Example POST /orders HTTP/1.1 [various headers] HTTP/1.1 400 Bad Request [various other headers] [ { "code" : "23" "propertyPath": "item.size", "message": "Size must not be null" }, ] APIbucks
  • 28. #WISSENTEILEN // Bean Validation Exception Mapper @Provider public class ValidationExceptionMapper implements ExceptionMapper<ConstraintViolationException> { @Override public Response toResponse(...) { List<...> errors = e.getConstraintViolations().stream() .map(error -> new ValidationError(error)) .collect(Collectors.toList()); return Response.status(BAD_REQUEST) .type("application/json") .entity(errors).build(); } APIbucks
  • 29. #WISSENTEILEN Scalability • Caching (Cache-Control & ETAG Header) • „The Web is your Friend“ • Revalidation with Conditional GET & PUT • Rate Limiting (X-Rate-Limit-* Header) • Begrenzung von Zugriffen auf eine API • Schränkt missbräuchliche Datenzugriffe ein • Realisierung via Proxy / API Gateway (oder im Service) {?} Web-API Design by Example
  • 30. #WISSENTEILEN // Caching with Cache-Control Header Example GET /orders/1234 [various other headers] HTTP/1.1 200 Ok [various other headers] Cache-Control: private, no-store, max-age=3600 „Only client side caching. Valid for 3600 sec. Must not be stored on disc.“ APIbucks
  • 31. #WISSENTEILEN // Caching with Cache-Control Header Example @GET @Path("/{id}") public Response getProduct(Long productId) { ... CacheControl cacheControl = new CacheControl(); cacheControl.setMaxAge(300); cacheControl.setPrivate(true); cacheControl.setNoStore(true); return Response.status(Status.OK).entity(...) .cacheControl(cacheControl) .build(); } APIbucks
  • 32. #WISSENTEILEN // Conditional GET Example GET /orders/1234 [various other headers] HTTP/1.1 200 Ok [various other headers] Cache-Control: private, no-store, max-age=3600 ETag: "1234567890987654321" APIbucks
  • 33. #WISSENTEILEN // Conditional GET Example @GET @Path("/{id}") public Response getProduct(Long productId) { ResponseBuilder builder = request.evaluatePreconditions(createEntityTag(...)); if (builder != null) { return builder.cacheControl(createControl()).build(); } return Response.status(Status.OK).entity(...) .cacheControl(createControl()) .tag(tag) .build(); } APIbucks
  • 34. #WISSENTEILEN // Conditional GET Example GET /orders/1234 HTTP/1.1 [various other headers] If-None-Match: "1234567890987654321" HTTP/1.1 304 Not Modified [various other headers] Cache-Control: private, no-store, max-age=3600 Modified since? No, 304 (Not Modified). Yes, 200 (Ok) plus Data. APIbucks
  • 35. #WISSENTEILEN // Rate-Limit Filter Example @GET @Path("/{id}") @Limited(rateLimit = 3, timeFrame = 10000) public Response getOrder(Long orderId) { ... return Response.status(Status.OK) .entity(...) .build(); } APIbucks
  • 36. #WISSENTEILEN // Rate-Limit Filter Example @Limited @Provider @Priority(Priorities.AUTHENTICATION) public class RateLimitPerTimeFrameFilter implements ContainerRequestFilter { @Context private ResourceInfo resourceInfo; public void filter(...) throws IOException { ... } } APIbucks
  • 37. #WISSENTEILEN // Rate-Limit example - first request GET /orders/1234 [various other headers] HTTP/1.1 200 Ok [various other headers] X-Rate-Limit-Limit: 3 X-Rate-Limit-Remaining: 2 X-Rate-Limit-Reset: 9 APIbucks
  • 38. #WISSENTEILEN // Rate-Limit example – second request GET /orders/1234 [various other headers] HTTP/1.1 200 Ok [various other headers] X-Rate-Limit-Limit: 3 X-Rate-Limit-Remaining: 1 X-Rate-Limit-Reset: 8 APIbucks
  • 39. #WISSENTEILEN // Rate-Limit example – third request GET /orders/1234 [various other headers] HTTP/1.1 429 Too many requests [various other headers] X-Rate-Limit-Limit: 3 X-Rate-Limit-Remaining: 0 X-Rate-Limit-Reset: 7 APIbucks
  • 40. #WISSENTEILEN Security • 401 „Unauthorized“ == „Unauthenticated“! • 403 „Forbidden“ == „ Unauthorized“! • Token-based Security mit JSON Web Token • Role-based Access Control {?} Web-API Design by Example
  • 41. #WISSENTEILEN // Bearer header example (restricted to customer) DELETE /orders/1234 [various other headers] HTTP/1.1 401 Unauthorized [various other headers] APIbucks
  • 42. #WISSENTEILEN // Bearer header example (restricted to customer) DELETE /orders/1234 Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpX... [various other headers] HTTP/1.1 204 No content [various other headers] APIbucks
  • 43. #WISSENTEILEN // JWT Authorization Filter Example DecodedJWT jwt = JWT .require(Algorithm.RSA256((RSAKey)publicKey)) .withIssuer("http://my-sso-server/auth/") .build .verify(token); String userId = jwt.getSubject(); String userName = jwt.getClaim("username").asString(); String email = jwt.getClaim("email").asString(); APIbucks
  • 44. #WISSENTEILEN // RolesAllowed Example @POST @RolesAllowed({"customer"}) public Response createOrder(NewOrder newOrder) { ... OrderDTO createdOrder = ... return Response.status(201) .entity(createdOrder) .build(); } APIbucks
  • 45. #WISSENTEILEN Documentation • OpenAPI Specification (OAS) • fka Swagger RESTful API Documentation Specification • (voll-) automatisierte Generierung (auch zur Laufzeit) • Export in diverse Formate (e.g. AsciDoc, HTML, PDF) • Unterstützung bei API First Design {?} Web-API Design by Example
  • 46. #WISSENTEILEN Swagger / Open API Specification (OAS) Web-API Design by Example Design mit Swagger Editor Build mit Swagger Codegen Dokumentiere mit Swagger-UI
  • 47. #WISSENTEILEN 3rd Party Tools mit Swagger/OAS Unterstützung • Teste API Operation mit Postman • Teste Consumer-driven Contracts mit Pact • Implementiere client-seitige Validierung auf Basis von JSON- Schema • Dokumentiere mit ReDoc & Asciidoc (z.B. PDF) Web-API Design by Example
  • 48. #WISSENTEILEN // Swagger Annotations Example (API Operation & Responses) @POST @ApiOperation(value = "Create a new order") @ApiResponses(@ApiResponse(code = 201, message = "Order created", response = OrderDto.class)) @Transactional public Response createOrder(@ApiParam(value = "new order") NewOrder newOrder) { ... } APIbucks
  • 49. #WISSENTEILEN // Swagger Bootstrap Servlet Example @WebServlet(loadOnStartup = 1) public class SwaggerBootstrap extends HttpServlet { @Override public void init(ServletConfig c)throws ServletException { super.init(c); BeanConfig beanConfig = new BeanConfig(); ... beanConfig.setBasePath(...); // API Base-Path beanConfig.setResourcePackage(...); beanConfig.setScan(true); } } APIbucks
  • 50. #WISSENTEILEN <!-- download swagger-ui --> <plugin> <artifactId>maven-dependency-plugin</artifactId> <executions> <execution> <id>swagger ui</id> <phase>prepare-package</phase> <goals> <goal>unpack</goal> </goals> <configuration> <artifactItems> <artifactItem> <groupId>org.webjars.npm</groupId> <artifactId>swagger-ui-dist</artifactId> <version>${version.swagger-ui}</version> </artifactItem> </artifactItems> <outputDirectory>${project.build.directory}/swagger- ui</outputDirectory> </configuration> </execution> </executions> </plugin> <!-- add swagger-ui to artefact --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>2.6</version> <configuration> <webResources combine.children="append"> <resource> <directory>${project.build.directory}/swagger-ui/META- INF/resources/webjars/swagger-ui-dist/${version.swagger- ui}</directory> <excludes> <exclude>index.html</exclude> </excludes> </resource> </webResources> </configuration> </plugin> APIbucks Pro Tipp
  • 53. #WISSENTEILEN Was ist nun der beste Ansatz eine API zu entwickeln? • API-First Design • Geräteunabhängiger Softwareentwurf • Erster Schritt: Entwurf & Dokumentation einer API • Code-First • Developers Choice J {?} Web-API Design by Example
  • 55. #WISSENTEILEN YOUR API IS THE FIRST USER INTERFACE OF YOUR APPLICATION
  • 56. #WISSENTEILEN YOUR API COMES FIRST, THEN THE IMPLEMENTATION
  • 57. #WISSENTEILEN YOUR API IS DESCRIBED (AND MABY EVEN SELF-DESCRIPTIVE)
  • 58. #WISSENTEILEN API-First Design Lifecyce! #1 – Planen #2 – Entwerfen & Validieren #3 – Überarbeiten #4 – Testen #5 – Implementieren #6 – Betreiben & Lernen (zurück zu #1) Web-API Design by Example {?}
  • 61. #WISSENTEILEN Be pragmaticIts pragmatic if it works for you and your consumers
  • 62. #WISSENTEILEN „Das* API ist das UI des Entwicklers.“ (*wer möchte, darf auch “die API“ sagen)
  • 63. #WISSENTEILEN „Entscheidend ist, dass das API aus Sicht des Entwicklers konsistent und leicht anwendbar ist.
  • 65. Kontakt STEPHAN MÜLLER ENTERPRISE ARCHITECT stephan.mueller@openknowledge.de +49 (0)441 4082 – 0 @_openknowledge OFFENKUNDIGGUT #WISSENTEILEN
  • 66. Bildnachweise #01: © dzone.com #46: © swagger.io #50: © swagger.io All other pictures inside this presentation orginate from pixabay.com or were created by my own. #WISSENTEILEN