SlideShare ist ein Scribd-Unternehmen logo
1 von 97
Downloaden Sie, um offline zu lesen
@ArneLimburg @_openknowledge #WISSENTEILEN
API Versionierung
im Projektalltag
ÜBER UNS
•  Enterprise Architect bei der
OPEN KNOWLEDGE GmbH
•  Themen
•  Microservices
•  APIs
•  Architektur
•  Technologie (Java EE)
Arne Limburg
@ArneLimburg @_openknowledge #WISSENTEILEN
Mapping-Schichten
sind das Tor zur
Versionierungshölle
KLASSISCHE ARCHITEKTUR
Database
Business
Frontend
KLASSISCHE ARCHITEKTUR
Database
Business
Frontend
OR-Mapping
DTO-Mapping
JSON-Mapping
VIER MODELLE
OR-Mapping
DTO-Mapping
JSON-Mapping
{
"parent": {...}
...}
{
"parent": {...}
...}
KLASSISCHE ARCHITEKTUR
Business
Frontend
Client
VERSCHIEDENE MODELLE
Mapping
Schnittstelle
VERSCHIEDENE MODELLE
Mapping
Schnittstelle
VERSCHIEDENE MODELLE
Mapping
Schnittstelle
Schnittstelle
DTO-SCHICHT TO THE RESCUE?
Mapping
DTO-SCHICHT TO THE RESCUE?
Mapping
Mapping
DTO-SCHICHT TO THE RESCUE?
Mapping
JEDEM CLIENT SEINE SCHNITTSTELLE
Mapping Mapping
JEDEM CLIENT SEINE SCHNITTSTELLE
Mapping Mapping
Mapping Mapping
@ArneLimburg @_openknowledge #WISSENTEILEN
Willkommen in der
Versionierungshölle
VERSCHIEDENE SCHNITTSTELLEN
Mapping Mapping
Mapping Mapping
VERSCHIEDENE SCHNITTSTELLEN
Mapping Mapping
Mapping Mapping
DOMAIN DRIVEN DESIGN
DOMAIN DRIVEN DESIGN
„For most software projects, the primary focus
should be on the domain and domain logic“
Eric Evans, Domain-Driven Design, Addison-Wesley, © Eric Evans, 2004
DOMÄNE
End User
Domain
Expert
Technical
Expert
Translation
Ist auf Dauer teuer
sogar sehr teuer
UBIQUITOUS LANGUAGE
End User
Domain
Expert
Technical
Expert
Fachsprache als Basis
Eindeutige Begriffe
Durchgängige Nutzung
DOMAIN DRIVEN DESIGN
„Complex Domain Design
should be based on a model “
Eric Evans, Domain-Driven Design, Addison-Wesley, © Eric Evans, 2004
DOMÄNENMODELL
Repräsentation der Domäne
Fachlich korrekt und konsistent
Weiterentwicklung durch alle Beteiligten
DOMÄNENMODELL
Repräsentation der Domäne
Fachlich korrekt und konsistent
Weiterentwicklung durch alle Beteiligten
„Das Domänenmodell ist das Bindeglied
zwischen Domänenexperten und
Entwicklern“
Eric Evans, Domain-Driven Design, Addison-Wesley, © Eric Evans, 2004
DOMÄNENMODELL ALS API
Schnittstelle
How to escape from
Versioning Hell?
Tolerant Reader Pattern
Tolerant gegenüber unbekannten Feldern
Umgang mit x-extensible-enum
http://zalando.github.io/restful-api-guidelines
EXKURS X-EXTENSIBLE-ENUM
Beispiel
address_type:
type: string
x-extensible-enum:
- private
- business
Tolerant Reader Pattern
Tolerant gegenüber unbekannten Feldern
Umgang mit x-extensible-enum
Tolerant gegenüber unbekannten Statuscodes
http://zalando.github.io/restful-api-guidelines
HTTP Status 301 folgen
TOLERANT READER PATTERN
http://www.example.com/addresses/42
à Liefert Addresse
{
street: {
"name": "Poststraße",
"number": "1",
},
"city": "26122 Oldenburg"
}
TOLERANT READER PATTERN
http://www.example.com/addresses/42
Attribut hinzufügen
{
street: {
"name": "Poststraße",
"number": "1",
"additionalAdressLine": "2. Obergeschoss"
},
"city": "26122 Oldenburg"
}
TOLERANT READER PATTERN
Server schickt
{
street: {
"name": "Poststraße",
"number": "1",
"additionalAdressLine":
"2. Obergeschoss"
}...
}
http://www.example.com/addresses/42
Client erwartet
{
street: {
"name": "Poststraße",
"number": "1",
}...
}
TOLERANT READER PATTERN
http://www.example.com/addresses/42
Attribut-Umbenennung
{
street: {
"name": "Poststraße",
"streetName": "Poststraße",
"number": "1",
"houseNumber": "1",
},
"city": "26122 Oldenburg"
}
TOLERANT READER PATTERN
http://www.example.com/addresses/42
à Abwärtskompatible Änderungen: Umbenennen durch Kopieren
{
street: {
"name": "Poststraße",
"streetName": "Poststraße",
"number": "1",
"houseNumber": "1",
},
"city": "26122 Oldenburg"
}
Und was ist, wenn der Client kein
Tolerant Reader ist?
PROJEKTIONEN
// Client kann entscheiden, welche Felder er bekommen möchte
// Facebook Style
GET /addresses/3?fields=street,city
GET /addresses/3?fields=street.name,street.number,city
// LinkedIn Style
GET /addresses/3?fields=street:(name,number),city
OK, so soll sich
der Client verhalten.
Aber was ist mit dem Server?
Photo by Irene Fertik, USC News Service. Copyright 1994, USC.
„Be conservative in what you do,
Be liberal in what you accept
from others“
RFC 793, Robustness Principal (John Postel)
Es darf nichts entfernt werden
Keine Veränderung von Verarbeitungsregel
Optionales darf nie Required werden
http://zalando.github.io/restful-api-guidelines
Alles was hinzugefügt wird, muss optional sein
MAGNANIMOUS WRITER PATTERN
Server schickt
{
street: {
"name": "Poststraße",
"streetName": "Poststraße",
"number": "1",
"houseNumber": "1“
}...
}
http://www.example.com/addresses/42
Client erwartet
{
street: {
"name": "Poststraße",
"number": "1",
}...
}
http://tenderware.blogspot.de/2011/05/magnanimous-writer.html
MAGNANIMOUS WRITER PATTERN
Server schickt
{
street: {
"name": "Poststraße",
"streetName": "Poststraße",
"number": "1",
"houseNumber": "1“
}...
}
http://www.example.com/addresses/42
Client erwartet
{
street: {
"streetName": "Poststraße",
"houseNumber": "1",
}...
}
http://tenderware.blogspot.de/2011/05/magnanimous-writer.html
MAGNANIMOUS WRITER PATTERN
Server erwartet
PUT http://www.example.com/addresses/42
Client schickt
{
street: {
"name": "Poststraße",
"number": "1",
}...
}
http://tenderware.blogspot.de/2011/05/magnanimous-writer.html
MAGNANIMOUS WRITER PATTERN
PUT http://www.example.com/addresses/42
Client schickt
{
street: {
"name": "Poststraße",
"number": "1",
}...
}
http://tenderware.blogspot.de/2011/05/magnanimous-writer.html
Server erwartet
{
street: {
"name": "Poststraße",
"streetName": "Poststraße",
"number": "1",
"houseNumber": "1“
}...
}
oder
oder
MAGNANIMOUS WRITER PATTERN
PUT http://www.example.com/addresses/42
Client schickt
{
street: {
"streetName": "Poststraße",
"houseNumber": "1",
}...
}
http://tenderware.blogspot.de/2011/05/magnanimous-writer.html
Server erwartet
{
street: {
"name": "Poststraße",
"streetName": "Poststraße",
"number": "1",
"houseNumber": "1“
}...
}
oder
oder
MAGNANIMOUS WRITER UND XML
http://www.example.com/.../street
à Abwärtskompatible Änderungen
<street>
<name>Poststraße</name>
<houseNumber>0815</...>
</customer>
<xs:schema xmlns:xs:="...">
<xs:complexType name="streetType">
<xs:sequence>
...
<xs:element
name="houseNumber"
type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
MAGNANIMOUS WRITER UND XML
http://www.example.com/.../street
à Abwärtskompatible Änderungen
à Version 1.1
<customer>
<name>Max Mustermann</name>
<houseNumber>0815</...>
<number>0815</number>
</customer>
<xs:sequence>
...
<xs:element ...
name="houseNumber“
minOccurs="0"/>
<xs:element ...
name="number“
minOccurs="0"/>
</xs:sequence>
MAGNANIMOUS WRITER UND XML
http://www.example.com/.../street
à Abwärtskompatible Änderungen
à Version 1.1
<customer>
<name>Max Mustermann</name>
<houseNumber>0815</...>
<number>0815</number>
</customer>
<xs:sequence>
...
<xs:element ...
name="houseNumber“
minOccurs="0"/>
<xs:element ...
name="number“
minOccurs="0"/>
<xs:any minOccurs="0"/>
<xs:anyAttribute
processContents="lax"/>
MAGNANIMOUS WRITER UND XML
à Offizieller Versionssupport seit XML-Schema 1.1
<schema ... xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning">
<complexType name="street" vc:maxVersion="1.3">
...
</complexType>
<complexType name="street" vc:minVersion="2.0">
...
</complexType>
</schema>
MAGNANIMOUS WRITER UND JAVA
public String getName() {
return getStreetName();
}
public void setName(String name) {
setStreetName(name);
}
PUT UND NULL VALUES
public String getName() {
return getStreetName();
}
public void setName(String name) {
setStreetName(name);
}
MERGE PATCH UND NULL VALUES
PATCH /addresses/42 HTTP/1.1
Content-Type: application/merge-patch+json
Client schickt
{
street: {
"name": null,
}...
}
https://tools.ietf.org/html/rfc7396
MERGE PATCH UND NULL VALUES
public class Street {
private String streetName;
private String streetNumber;
public void setName(String name) { setStreetName(...
public void setNumber(String number) { setStreetNum...
}
Wird mit null aufgerufen
Wird gar nicht aufgerufen
MERGE PATCH UND NULL VALUES
public class Street {
private String streetName; // = null
private String streetNumber; // = null
public void setName(String name) { setStreetName(...
public void setNumber(String number) { setStreetNum...
}
MERGE PATCH UND NULL VALUES
public class Street {
private String streetName; // = null
private String streetNumber; // = null
public void setName(String name) { setStreetName(...
public void setNumber(String number) { setStreetNum...
}
Simple Solution:
Don‘t use PATCH at all
MERGE PATCH UND NULL VALUES
public class Street {
private String streetName; // = null
private String streetNumber; // = null
public void setName(String name) { setStreetName(...
public void setNumber(String number) { setStreetNum...
}
Advanced Solution:
Use initial values
MERGE PATCH UND NULL VALUES
public class Street {
private String streetName = "<initial value>";
private String streetNumber = "<initial value>";
public void setName(String name) { setStreetName(...
public void setNumber(String number) { setStreetNum...
}
MERGE PATCH UND NULL VALUES
public class Street {
private String streetName = "<initial value>";
private String streetNumber = "<initial value>";
public void setName(String name) { setStreetName(...
public void setNumber(String number) { setStreetNum...
}
Wird mit null aufgerufen
Wird gar nicht aufgerufen
MERGE PATCH UND NULL VALUES
public class Street {
private String streetName; // = null
private String streetNumber = "<initial value>";
public void setName(String name) { setStreetName(...
public void setNumber(String number) { setStreetNum...
}
Wird mit null aufgerufen
Wird gar nicht aufgerufen
ABWÄRTSKOMPATIBILITÄT
http://www.example.com/addresses/42
à Abwärtskompatible Änderungen: Umbenennen durch Kopieren
{
street: {
"name": "Poststraße",
"streetName": "Poststraße",
"number": "1",
"houseNumber": "1",
},
"city": "26122 Oldenburg"
}
Geht da noch mehr?
ABWÄRTSKOMPATIBILITÄT
http://www.example.com/addresses/42
à Zusammenführen und Teilen von Attributen
{
street: {
...
"streetName": "Poststraße",
"houseNumber": "1",
"addressLine1": "Poststraße 1",
}
...
}
ABWÄRTSKOMPATIBILITÄT
http://www.example.com/addresses/42
à Herausforderungen: Zusammenführen von Attributen
{
street: {
...
"streetName": "Poststraße",
"houseNumber": "1",
"addressLine1": "Poststraße 1",
}
...
}
ABWÄRTSKOMPATIBILITÄT
http://www.example.com/addresses/42
à Herausforderungen: Teilen von Attributen
{
street: {
...
"addressLine1": "Poststraße 1",
}
"city": "26122 Oldenburg",
"zipCode": "26122",
"cityName": "Oldenburg"
}
ABWÄRTSKOMPATIBILITÄT
http://www.example.com/addresses/42
à Herausforderungen: Ebene von Attributen ändern
{
street: {
...
"addressLine1": "Poststraße 1"
}
"addressLine1": "Poststraße 1",
...
}
ABWÄRTSKOMPATIBILITÄT
http://www.example.com/addresses/42
à Herausforderungen: Ebene von Attributen ändern
{
...
"zipCode": "26122",
"cityName": "Oldenburg",
"location": {
"zipCode": "26122",
"cityName": "Oldenburg"
}
}
ABWÄRTSKOMPATIBILITÄT
http://www.example.com/addresses/42
à Herausforderungen: Ebene von Attributen ändern
{
...
"zipCode": "26122",
"cityName": "Oldenburg",
"location": {
"zipCode": "26122",
"cityName": "Oldenburg"
}
}
Bei jeder Modelländerung muss
eine Migrationsstrategie
einbezogen werden!
ABWÄRTSKOMPATIBILITÄT
public String getCity() {
return getZipCode() + " " + getCityName();
}
public void setCity(String city) {
setZipCode(city.substring(0, 5));
setCityName(city.substring(5).trim());
}
Was ist daran jetzt besser als an
einer Mapping-Schicht?
Migrations-Strategie für jede Attributänderung
Code für Migration sehr nah an der Schnittstelle
Migrations-Regeln innerhalb des Objekts
Code unabhängig
ABWÄRTSKOMPATIBILITÄT
{
street: {
"name": "Poststraße",
"streetName": "Poststraße",
"number": "1",
"houseNumber": "1",
"addressLine1": "Post... 1",
"addressLine2": ""
}
"addressLine1": "Poststraße 1",
"addressLine2": "",
"city": "26122 Oldenburg",
"zipCode": "26122",
"cityName": "Oldenburg",
"location": {
"zipCode": "26122",
"cityName": "Oldenburg"
}
}
http://www.example.com/v1/addresses/42
à Bisher nur abwärtskompatible Änderungen
ABWÄRTSKOMPATIBILITÄT
{
street: {
"name": "Poststraße",
"streetName": "Poststraße",
"number": "1",
"houseNumber": "1",
"addressLine1": "Post... 1",
"addressLine2": ""
}
"addressLine1": "Poststraße 1",
"addressLine2": "",
"city": "26122 Oldenburg",
"zipCode": "26122",
"cityName": "Oldenburg",
"location": {
"zipCode": "26122",
"cityName": "Oldenburg"
}
}
http://www.example.com/v1/addresses/42
à Viele Attribute deprecated
Wie kann ich Attribute entfernen?
Incompatible Change
vs. Breaking Change
http://zalando.github.io/restful-api-guidelines
WELCHE CLIENTS NUTZEN MICH?
PROVIDER CONTRACT
ProviderConsumer
A
C
B
CONSUMER CONTRACTS
ProviderConsumer
A
C
B
CONSUMER CONTRACTS
YAGNI - You Aren’t Gonna Need It!
ProviderConsumer
A
B
C
CONSUMER-DRIVEN CONTRACT TEST
Consumer ProviderConsumer
Contract
CONSUMER-DRIVEN CONTRACT TEST
•  Versteht der Provider die Anfragen?
•  Liefert er die erwarteten Antworten?
Consumer
Provider
Stub
Provider
Request
Generator
•  Erzeugt der
Consumer die
erwarteten Anfragen?
•  Kann er mit den
Antworten umgehen?
CONSUMER-DRIVEN CONTRACT TEST
•  Startet Provider
•  Interaktionen abspielen Consumer
Provider
Stub
Provider
Request
Generator
•  Unit-Tests
•  Responses auf
erwartete Requests
Interactions
CONSUMER-DRIVEN CONTRACT TEST
•  Versteht der Provider die Anfragen?
•  Liefert er die erwarteten Antworten?
Consumer
Provider
Stub
Provider
Request
Generator
•  Erzeugt der
Consumer die
erwarteten Anfragen?
•  Kann er mit den
Antworten umgehen?
Und wenn ich meine Consumer
nicht kenne?
VERSIONSSPRUNG
{
street: {
"name": "Poststraße",
"streetName": "Poststraße",
"number": "1",
"houseNumber": "1",
"addressLine1": "Post... 1",
"addressLine2": ""
}
"addressLine1": "Poststraße 1",
"addressLine2": "",
"city": "26122 Oldenburg",
"zipCode": "26122",
"cityName": "Oldenburg",
"location": {
"zipCode": "26122",
"cityName": "Oldenburg"
}
}
http://www.example.com/v1/addresses/42
à Bisher nur abwärtskompatible Änderungen
INKOMPATIBLE ÄNDERUNG
http://www.example.com/v2/addresses/42
à Versionssprung
{
"addressLine1": "Poststraße 1",
"addressLine2": "",
"location": {
"zipCode": "26122",
"cityName": "Oldenburg"
}
}
INKOMPATIBLE ÄNDERUNG
Version 2.0
ist nur inkompatibel zu 1.0!
Version 2.0 ist identisch zu 1.x!
Das erleichtert das Mapping
zwischen den Versionen!
Ein solcher Versionssprung ist
nicht anforderungsgetrieben,
sondern viel besser und
langfristiger planbar
•  Über URL-Pfad
/v2/addresses
•  Über Query-Parameter
/addresses?version=v2
•  Über Version-Header
Api-Version: v2
•  Über Version-Attribut am Media-Type
application/xml;version=v2
•  Über Media-Type
application/vnd.de.openknowledge+v2+json
ERMITTELN DER VERSION
ABWÄRTSKOMPATIBILITÄT
Schnittstelle Schnittstelle
{ street: {
"name": "Poststraße",
"streetName": "Poststraße",
"number": "1",
"houseNumber": "1",
"addressLine1": "Post... 1",
"addressLine2": ""
}
"addressLine1": "Poststraße 1",
"addressLine2": "",
"city": "26122 Oldenburg",
"zipCode": "26122",
"cityName": "Oldenburg",
"location": {
"zipCode": "26122",
"cityName": "Oldenburg"
}
}
{
"addressLine1": "Poststraße 1",
"addressLine2": "“,
"location": {
"zipCode": "26122",
"cityName": "Oldenburg"
}
}
V1 V2-SNAPSHOT
ABWÄRTSKOMPATIBILITÄT
Schnittstelle Schnittstelle
{ street: {
"name": "Poststraße",
"streetName": "Poststraße",
"number": "1",
"houseNumber": "1",
"addressLine1": "Post... 1",
"addressLine2": ""
}
"city": "26122 Oldenburg",
"zipCode": "26122",
"cityName": "Oldenburg",
"addressLine1": "Poststraße 1",
"addressLine2": "“,
"location": {
"zipCode": "26122",
"cityName": "Oldenburg"
}
}
{
"addressLine1": "Poststraße 1",
"addressLine2": "“,
"location": {
"zipCode": "26122",
"cityName": "Oldenburg"
}
}
V1 V2-SNAPSHOT
ABWÄRTSKOMPATIBILITÄT
Schnittstelle
Schnittstelle
{ street: {
"name": "Poststraße",
"streetName": "Poststraße",
"number": "1",
"houseNumber": "1",
"addressLine1": "Post... 1",
"addressLine2": ""
}
...
}
{
"addressLine1": "Poststraße 1",
"addressLine2": "“,
"city": {
"zipCode": "26122",
"cityName": "Oldenburg"
}
}
V1 V3-SNAPSHOT
Schnittstelle
{ "addressLine1": "Poststraße 1",
"addressLine2": "“,
"location": {
"zipCode": "26122",
"cityName": "Oldenburg"
},
"city": {
"zipCode": "26122",
"cityName": "Oldenburg"
}} V2
GRÜNE WIESE
Server
REST
Client
SCHLANKE ARCHITEKTUR ZU BEGINN
Schnittstelle
V1-SNAPSHOT
AUTOMATISIERTES MAPPING
Schnittstelle Schnittstelle
{ street: {
"name": "Poststraße",
"streetName": "Poststraße",
"number": "1",
"houseNumber": "1",
"addressLine1": "Post... 1",
"addressLine2": ""
}
"addressLine1": "Poststraße 1",
"addressLine2": "",
"city": "26122 Oldenburg",
"zipCode": "26122",
"cityName": "Oldenburg",
"location": {
"zipCode": "26122",
"cityName": "Oldenburg"
}
}
{
"addressLine1": "Poststraße 1",
"addressLine2": "“,
"location": {
"zipCode": "26122",
"cityName": "Oldenburg"
}
}
V1 V2-SNAPSHOT
FAZIT
Schnittstelle Schnittstelle
{ street: {
"name": "Poststraße",
"streetName": "Poststraße",
"number": "1",
"houseNumber": "1",
"addressLine1": "Post... 1",
"addressLine2": ""
}
"addressLine1": "Poststraße 1",
"addressLine2": "",
"city": "26122 Oldenburg",
"zipCode": "26122",
"cityName": "Oldenburg",
"location": {
"zipCode": "26122",
"cityName": "Oldenburg"
}
}
{
"addressLine1": "Poststraße 1",
"addressLine2": "“,
"location": {
"zipCode": "26122",
"cityName": "Oldenburg"
}
}
V1 V2-SNAPSHOT
It‘s never too late
Don‘t break the Client
Plane neue Versionen
Behalte alte Versionen
FRAGEN & DISKUSSION
? ? ?

Weitere ähnliche Inhalte

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 AIOPEN 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 CloudOPEN 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 ImputationOPEN 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
 
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 & CoOPEN KNOWLEDGE GmbH
 
Shared Data in verteilten Architekturen
Shared Data in verteilten ArchitekturenShared Data in verteilten Architekturen
Shared Data in verteilten ArchitekturenOPEN KNOWLEDGE GmbH
 
Machine Learning mit TensorFlow.js
Machine Learning mit TensorFlow.jsMachine Learning mit TensorFlow.js
Machine Learning mit TensorFlow.jsOPEN 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 NetzeOPEN KNOWLEDGE GmbH
 
Shared Data in verteilten Systemen
Shared Data in verteilten SystemenShared Data in verteilten Systemen
Shared Data in verteilten SystemenOPEN KNOWLEDGE GmbH
 
Mehr Sicherheit durch Automatisierung
Mehr Sicherheit durch AutomatisierungMehr Sicherheit durch Automatisierung
Mehr Sicherheit durch AutomatisierungOPEN KNOWLEDGE GmbH
 
API-Design, Microarchitecture und Testing
API-Design, Microarchitecture und TestingAPI-Design, Microarchitecture und Testing
API-Design, Microarchitecture und TestingOPEN 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: QuarkusOPEN 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
 
Das ist doch alles nur Frontend - Wer braucht da schon Architektur?
Das ist doch alles nur Frontend - Wer braucht da schon Architektur?Das ist doch alles nur Frontend - Wer braucht da schon Architektur?
Das ist doch alles nur Frontend - Wer braucht da schon Architektur?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.
 
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!
 
Das ist doch alles nur Frontend - Wer braucht da schon Architektur?
Das ist doch alles nur Frontend - Wer braucht da schon Architektur?Das ist doch alles nur Frontend - Wer braucht da schon Architektur?
Das ist doch alles nur Frontend - Wer braucht da schon Architektur?
 

API-Versionierung im Projektalltag