Upload
proidea
View
189
Download
1
Embed Size (px)
DESCRIPTION
Why REST API should be backward compatible and why it is hard to achieve. The talk will be about that and other problems we have encountered in Kontakt.io when building platform for worldwide services.
Citation preview
About me
Łukasz Wierzbicki • +10 years of
professional experience
• software engineer, architect, manager
Motivation
• lots of ideas how to mark versions
• lots of theory
• ...little practise
• any actual solution?
Why do we need versioning?
• new fields in particular
resource
• we don't need some
fields any longer
• we're startup
• people are already
using our API
Why, why, why?
Assumptions
• business logic returns model
• controllers return views
• object-json/xml/? mapping done
transparently
Possibilities
• several versions of model,
• model as a “view”
• one object mapper
cons: a lot of code, DAOs and services pros: don't see any
no 1
Possibilities, flow
cons: a lot of code, DAOs and services pros: don't see any
no 1
Dao 1
Dao 2
Service 2
Service 1 Backend 1
Backend 2
Model 2
Model 1 Controller 1
Controller 2 Response
Response
Version Router Request
Possibilities • one model
• converters
• several versions of view objects
• one object mapper
no 2
Possibilities, flow
no 2
cons: still a lot of boilerplate code pros: less code than previously
Dao Service
Backend 1
Backend 2
Converter 1
Converter 2
Response
Response
Version Router Request
Model
View 1
View 2
Controller 1
Controller 2
Model
Possibilities • one model
• one view/proxy factory
• several versions of dynamic proxies
• one object mapper
no 3
public class Address {
private final String street;
private final String city;
public Address(String street, String city) { super();
this.street = street; this.city = city;
}
public String getStreet() { return street;
}
public String getCity() { return city;
} }
@View public interface AddressV1 {
String getStreet(); @Property("city")
String getTown();
@Provider(Public.class ) Boolean getPublic();
class Public implements Provider<Address> { @Override
public Object get(Address source) { return true;
} }
}
Some code...
Model
Possibilities, flow
no 3
cons: some magic to write/handle pros: even less code to handle
Dao Service
Backend 1
Response
Response
Version Router Request
View 2
Controller 1
Controller 2
Proxy Factory
Backend 2
View.class
View 1
Possibilities
• one model
• view factory having list of properties
• map as a view
• one object mapper
no 4
Possibilities, flow
no 4
Dao Service
Backend 2
View Factory 1
Response
Response
Version Router Request
Map
Map
Controller 1
Controller 2
cons: some magic to write/handle pros: small amount of code, partial resources
View Factory 2
Backend 1
Possibilities • lots of combinations
• i.e. one view, one object mapper public class AddressView {
@Version("1", "2", "3") private String street;
@Version1 @Version3("town") private String city;
}
no ...
Our choice - no 4
• because it is easy to use
• because of less boilerplate code,
and we don't have time to make /
maintain it
• because we wanted to have
“partial resources”
How?
• converters get properties values and put them to maps
• include list: “length”, user.role”, “user.id”, “user.name”
• exclude list - great for small changes
• “generated fields” - when hotfix needed
• “mappings” - “name from model” -> “name in json”
Our api… foreword
• REST but not RESTful/
HATEOAS
• Just Http GETs and POSTs
• Verbs in paths, i.e.: create,
update, assign
Thank You!