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!