api-design: vorsicht vor der versioning-hölle!

62
@ArneLimburg @_openknowledge #WISSENTEILEN API Design – Beware of the versioning hell

Upload: open-knowledge-gmbh

Post on 22-Jan-2018

37 views

Category:

Software


2 download

TRANSCRIPT

Page 1: API-Design: Vorsicht vor der Versioning-Hölle!

@ArneLimburg @_openknowledge #WISSENTEILEN

API Design – Beware of the versioning hell

Page 2: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

GRÜNE WIESE

Server

REST

Client

Page 3: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

API DESIGN

Server

REST

Client

Page 4: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

API FIRST DESIGN

Server

Client

Page 5: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

API FIRST DESIGN

Page 6: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

API FIRST DESIGN

Mapping

Schnittstelle

Page 7: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

KLASSISCHE ARCHITEKTUR

Mapping

Schnittstelle

Backend

Frontend

Client

Page 8: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

KLASSISCHE ARCHITEKTUR

Backend

Frontend

Client

Page 9: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

KLASSISCHE ARCHITEKTUR

Mapping

Schnittstelle

Page 10: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

ÜBERFLÜSSIGEN CODE VERMEIDEN

Mapping

Schnittstelle

Page 11: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

SCHLANKE ARCHITEKTUR ZU BEGINN

Schnittstelle

Page 12: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

ÄNDERUNG AM MODELL

Schnittstelle

Page 13: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

VERSCHIEDENE MODELLE

Mapping

Schnittstelle

Page 14: API-Design: Vorsicht vor der Versioning-Hölle!

Schnittstelle

API Versioning | Arne Limburg

VERSCHIEDENE MODELLE

Mapping

Page 15: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

VERSCHIEDENE MODELLE

Mapping

Page 16: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

VERSCHIEDENE SCHNITTSTELLEN

Mapping

Mapping

Page 17: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

VERSCHIEDENE SCHNITTSTELLEN

Mapping

Page 18: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

VERSCHIEDENE SCHNITTSTELLEN

Mapping Mapping

Mapping Mapping

Page 19: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

VERSCHIEDENE SCHNITTSTELLEN

Mapping Mapping

Mapping Mapping

Page 20: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

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

Page 21: API-Design: Vorsicht vor der Versioning-Hölle!

DOMÄNE

End User

Domain Expert

Technical Expert

Translation Ist auf Dauer teuer sogar sehr teuer

API Versioning | Arne Limburg

Page 22: API-Design: Vorsicht vor der Versioning-Hölle!

UBIQUITOUS LANGUAGE

API Versioning | Arne Limburg

End User

Domain Expert

Technical Expert

Fachsprache als Basis

Eindeutige Begriffe

Durchgängige Nutzung

Page 23: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

DOMAIN DRIVEN DESIGN

„Complex Domain Design

should be based on a model “

Eric Evans, Domain-Driven Design, Addison-Wesley, © Eric Evans, 2004

Page 24: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

DOMÄNENMODELL

Repräsentation der Domäne

Fachlich korrekt und konsistent

Weiterentwicklung durch alle Beteiligten

Page 25: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

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

Page 26: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

VERSCHIEDENE MODELLE

Mapping

Schnittstelle

Page 27: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

VERSCHIEDENE MODELLE

Mapping Mapping

Mapping Mapping

Page 28: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

VERSCHIEDENE MODELLE

Mapping

Schnittstelle

Page 29: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

SCHLANKE ARCHITEKTUR

Mapping

Schnittstelle

Page 30: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

ABWÄRTSKOMPATIBILITÄT http://www.example.com/addresses/42 à Liefert Addresse { street: { "name": "Poststraße", "number": "1", }, "city": "26122 Oldenburg" }

Page 31: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

ABWÄRTSKOMPATIBILITÄT http://www.example.com/addresses/42 Attribut hinzufügen { street: { "name": "Poststraße", "number": "1", "additionalAdressLine": "2. Obergeschoss" }, "city": "26122 Oldenburg" }

Page 32: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

ABWÄRTSKOMPATIBILITÄT http://www.example.com/addresses/42 Attribut hinzufügen { street: { "name": "Poststraße", "number": "1", "additionalAdressLine": "2. Obergeschoss" }, "city": "26122 Oldenburg" }

Besondere Anforderung an den Client:

Unbekannte Attribute ignorieren à

Tolerant Reader Pattern

Page 33: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

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",

}...

}

Page 34: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

ABWÄRTSKOMPATIBILITÄT http://www.example.com/addresses/42 Attribut-Umbenennung { street: { "name": "Poststraße", "streetName": "Poststraße", "number": "1", "houseNumber": "1", }, "city": "26122 Oldenburg" }

Page 35: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

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" }

Page 36: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

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

Page 37: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

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

Page 38: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

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

„Be conservative in what you do,

Be liberal in what you expect“

Postels Law (John Postel)

Page 39: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

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

Page 40: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

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

Page 41: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

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>

Page 42: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

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>

Page 43: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

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"/>

Page 44: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

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>

Page 45: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

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?

Page 46: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

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", } ... }

Page 47: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

ABWÄRTSKOMPATIBILITÄT http://www.example.com/addresses/42 à Herausforderungen: Zusammenführen von Attributen { street: { ... "streetName": "Poststraße", "houseNumber": "1", "addressLine1": "Poststraße 1", } ... }

Page 48: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

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" }

Page 49: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

ABWÄRTSKOMPATIBILITÄT http://www.example.com/addresses/42 à Herausforderungen: Ebene von Attributen ändern { street: { ... "addressLine1": "Poststraße 1" } "addressLine1": "Poststraße 1", ... }

Page 50: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

ABWÄRTSKOMPATIBILITÄT http://www.example.com/addresses/42 à Herausforderungen: Ebene von Attributen ändern { ... "zipCode": "26122", "cityName": "Oldenburg", "location": { "zipCode": "26122", "cityName": "Oldenburg" } }

Page 51: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

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!

Page 52: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

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

Page 53: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

DOMÄNENMODELL ALS API

Schnittstelle

Page 54: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

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

Page 55: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

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

Page 56: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

INKOMPATIBLE ÄNDERUNG http://www.example.com/v2/addresses/42 à Versionssprung { "addressLine1": "Poststraße 1", "addressLine2": "", "location": { "zipCode": "26122", "cityName": "Oldenburg" } }

Page 57: API-Design: Vorsicht vor der Versioning-Hölle!

• Umbennen von Ressourcen à Http-Status-Code 301 „Moved Permanently“

• Semantische Änderung von Attributen à Anderen Namen vergeben

• Neue Version hat anderes Verhalten à Neue Schnittstelle

• PUT zum Setzen leerer Attribute à Unterscheidung zwischen nicht vorhanden und empty

WEITERE HERAUSFORDERUNGEN

API Versioning | Arne Limburg

Page 58: API-Design: Vorsicht vor der Versioning-Hölle!

•  Ü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

API Versioning | Arne Limburg

Page 59: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

DOMÄNENMODELL ALS API

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

Page 60: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

DOMÄNENMODELL ALS API 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

Page 61: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

FAZIT 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

Änderungen innerhalb einer Version sind fachlich

Migrations-Strategie für jede Attribut-Änderung

Mapping zwischen Versionen ist automatisierbar

Domänenmodell reflektiert immer aktuelle API

Page 62: API-Design: Vorsicht vor der Versioning-Hölle!

API Versioning | Arne Limburg

FRAGEN & DISKUSSION

? ? ?