Date post: | 15-Feb-2017 |
Category: |
Software |
Upload: | open-knowledge-gmbh |
View: | 128 times |
Download: | 2 times |
@ArneLimburg @_openknowledge
Schnittstellenevolutionmit VeRST
Versioned Represental State Transfer
VeRST | Arne Limburg
REST-Schnittstelle
http://www.example.com/addresses/42
Liefert Addresse
{
street: {
"name": "Poststraße",
"number": "1",
}
"city": "26122 Oldenburg"
}
VeRST | Arne Limburg
Was tun bei Weiterentwicklung?
http://www.example.com/addresses/42
Attribut-Umbenennung
{
street: {
"name": "Poststraße",
"streetName": "Poststraße",
"number": "1",
"houseNumber": "1",
}
"city": "26122 Oldenburg"
}
VeRST | Arne Limburg
Abwärtskompatible Weiterentwicklung
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"
}
VeRST | Arne Limburg
Abwärtskompatible Weiterentwicklung
http://www.example.com/v1/addresses/42
Abwärtskompatible Änderungen: Umbenennen durch Kopieren
{
street: {
"name": "Poststraße",
"streetName": "Poststraße",
"number": "1",
"houseNumber": "1",
}
"city": "26122 Oldenburg"
}
• Server muss mit beiden Varianten
als Parameter umgehen können
• Server muss beide Varianten als
Antwort liefern können
Tolerant Reader Pattern
VeRST | Arne Limburg
Abwärtskompatible Weiterentwicklung
http://www.example.com/v1/addresses/42
Abwärtskompatible Änderungen: Umbenennen durch Kopieren
{
street: {
"name": "Poststraße",
"streetName": "Poststraße",
"number": "1",
"houseNumber": "1",
}
"city": "26122 Oldenburg"
}
• Server muss mit beiden Varianten
als Parameter umgehen können
• Server muss beide Varianten als
Antwort liefern können
Tolerant Reader Pattern
„Be conservative in what you do, be liberal in what you
expect.“
Postels Law (Jon Postel)
VeRST | Arne Limburg
Abwärtskompatible Weiterentwicklung
http://www.example.com/v1/addresses/42
Abwärtskompatible Änderungen: Umbenennen durch Kopieren
{
street: {
"name": "Poststraße",
"streetName": "Poststraße",
"number": "1",
"houseNumber": "1",
}
"city": "26122 Oldenburg"
}
• Server muss mit beiden Varianten
als Parameter umgehen können
• Server muss beide Varianten als
Antwort liefern können
Tolerant Reader Pattern
Idee: Automatisierung durch Framework VeRST
VeRST | Arne Limburg
Abwärtskompatible Weiterentwicklung
public class Address {
private Street street;
private String city;
}
public class Street {
private String name;
private String number;
}
VeRST | Arne Limburg
Transformation durch Annotations
public class Address {
private Street street;
private String city;
}
public class Street {
@Deprecated
private String name;
@MovedFrom("name")
private String streetName;
@Deprecated
private String number;
@MovedFrom("number")
private String houseNumber;
}
VeRST | Arne Limburg
Transformation durch Annotations
public class Address {
private Street street;
private String city;
}
public class Street {
@Deprecated
private String name;
@MovedFrom("name")
private String streetName;
@Deprecated
private String number;
@MovedFrom("number")
private String houseNumber;
}
VeRST | Arne Limburg
Herausforderungen
http://www.example.com/v1/addresses/42
Zusammenführen und Teilen von Attributen
{
street: {
...
"streetName": "Poststraße",
"houseNumber": "1",
"addressLine1": "Poststraße 1",
}
...
}
VeRST | Arne Limburg
Zusammenführen von Attributen
http://www.example.com/v1/addresses/42
Herausforderungen: Zusammenführen und Teilen von Attributen
{
street: {
...
"streetName": "Poststraße",
"houseNumber": "1",
"addressLine1": "Poststraße 1",
}
...
}
VeRST | Arne Limburg
Teilen von Attributen
http://www.example.com/v1/addresses/42
Herausforderungen: Zusammenführen und Teilen von Attributen
{
street: {
...
"addressLine1": "Poststraße 1",
}
"city": "26122 Oldenburg",
"zipCode": "26122",
"cityName": "Oldenburg"
}
VeRST | Arne Limburg
Zusammenführen und Teilen von Attributen
http://www.example.com/v1/addresses/42
Herausforderungen: Zusammenführen und Teilen von Attributen
{
street: {
...
"addressLine1": "Poststraße 1",
}
"city": "26122 Oldenburg",
"zipCode": "26122",
"cityName": "Oldenburg"
}
Idee: Komplexe Transformationen über Java-Code
VeRST | Arne Limburg
Transformation über Java-Code
public class Address {
private Street street;
@Removed(CityProvider.class)
private String city;
@Added(CitySplitProvider.class)
private String zipCode;
@Added(CitySplitProvider.class)
private String cityName;
}
public class Street {
...
@Removed(StreetNamePr...class)
private String streetName;
@Removed(HouseNumberP...class)
private String houseNumber;
@Added(AddressLinePro...class)
private String addressLine1;
@Added(defaultValue = "")
private String addressLine2;
}
VeRST | Arne Limburg
Transformation über Java-Code
public class CitySplitProvider implements Provider<String> {
public String get(VersionContext versionContext) {
Address address = versionContext.getParent(Address.class);
String city = address.getCity();
if (versionContext.getPropertyName().equals("zipCode")) {
return city.substring(0, 5);
} else if (versionContext.getPropertyName().equals("cityName")){
return city.substring(6).trim();
} else {
throw new IllegalArgumentException(...);
}}}
VeRST | Arne Limburg
Ebene von Attributen ändern
http://www.example.com/v1/addresses/42
Herausforderungen: Ebene von Attributen ändern
{
street: {
...
"addressLine1": "Poststraße 1"
}
"addressLine1": "Poststraße 1",
...
}
VeRST | Arne Limburg
Ebene von Attributen ändern
http://www.example.com/v1/addresses/42
Herausforderungen: Ebene von Attributen ändern
{
...
"zipCode": "26122",
"cityName": "Oldenburg",
"location": {
"zipCode": "26122",
"cityName": "Oldenburg"
}
}
VeRST | Arne Limburg
Ebene von Attributen ändern
public class Address {
private Street street;
@MovedFrom(
"street/addressLine1")
private String addressLine1;
...
private City location;
}
public class City {
@MovedFrom("../zipCode")
private String zipCode;
@MovedFrom("../cityName")
private String cityName;
}
VeRST | Arne Limburg
Default-Werte für Attribute
public class Address {
private Street street;
@MovedFrom(
"street/addressLine1")
private String addressLine1;
@Added(defaultValue = " ")
private String addressLine2;
...
private City location;
}
public class City {
@MovedFrom("../zipCode")
private String zipCode;
@MovedFrom("../cityName")
private String cityName;
}
VeRST | Arne Limburg
Default-Werte für Attribute
public class Address {
private Street street;
@MovedFrom(
"street/addressLine1")
private String addressLine1;
@Added(defaultValue = " ")
private String addressLine2;
...
private City location;
}
public class City {
@MovedFrom("../zipCode")
private String zipCode;
@MovedFrom("../cityName")
private String cityName;
}
VeRST | Arne Limburg
Abwärtskompatible Weiterentwicklung
{
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
VeRST | Arne Limburg
Aufräumen
{
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
VeRST | Arne Limburg
Aufräumen
{
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
VeRST | Arne Limburg
Inkompatible Änderung
http://www.example.com/v2/addresses/42
Versionssprung
{
"addressLine1": "Poststraße 1",
"addressLine2": "",
"location": {
"zipCode": "26122",
"cityName": "Oldenburg"
}
}
VeRST | Arne Limburg
Version über URL
@Path("{version}/addresses")
public class AddressResource {
@GET
@Path("{id}")
public Address getAddress(@PathParam("id") String id) {
...
}
}
VeRST | Arne Limburg
Version über URL
@Path("{version}/addresses")
public class AddressResource {
@GET
@Path("{id}")
public Address getAddress(@PathParam("id") String id) {
...
}
}
VeRST | Arne Limburg
Versionierung über Annotations
@SupportedVersion(
version = "v2"
previous = AddressV1.class)
public class Address {
private Street street;
@MovedFrom("...")
private String addressLine1;
...
private City location;
}
public class City {
@MovedFrom("../zipCode")
private String zipCode;
@MovedFrom("../cityName")
private String cityName;
}
VeRST | Arne Limburg
Versionierung über Annotations
@SupportedVersion(
version = "v2"
previous = AddressV1.class)
public class Address {
private Street street;
@MovedFrom("...")
private String addressLine1;
...
private City location;
}
public class City {
@MovedFrom("../zipCode")
private String zipCode;
@MovedFrom("../cityName")
private String cityName;
}
@ArneLimburg @_openknowledge
Fragen? Try it out
https://github.com/openknowledge/jaxrs-versioning