Leif Åstrand
Product Manager
Comparing GWT
Transport Mechanisms
lördag 24 januari 15
Transport
lördag 24 januari 15
RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, url);
try {
builder.sendRequest(requestDataString, new Req...
Good
• It just works
Bad
• Low level
RequestBuilder
lördag 24 januari 15
Real world usage
8 %
lördag 24 januari 15
What to send?
lördag 24 januari 15
public class Contact {
private String name;
private int yearOfBirth;
private List<String> emailAddresses;
private Address ...
String data = contact.getName();
data += "," + contact.getYearOfBirth();
String[] parts = data.split(",");
contact.setName...
String data = contact.getName();
data += "," + contact.getYearOfBirth();
String[] parts = data.split(",");
contact.setName...
{
	 name: "John Doe",
	 yearOfBirth: 1900,
	 address: {
	 	 street: "Happy Street 1",
	 	 city: "Turku"
	 },
	 emailAddres...
JSONObject json = JSONParser.parseStrict(string).isObject();
contact.setName(json.get("name").isString().stringValue());
c...
Good
• It’s standard
• Human readable
format
• Compact format
Bad
• Not completely
typesafe
• Boilerplate
• Client only
JS...
What about the
server?
lördag 24 januari 15
ObjectMapper mapper = new ObjectMapper();
try {
Contact contact = mapper.readValue(string, Contact.class);
} catch (Variou...
Reflection
Code generation
lördag 24 januari 15
public static interface ContactMapper extends
ObjectMapper<Contact> {}
public Contact parseContact(String string) {
Contac...
Good
• Minimal boiler plate
• Can share code
between server and
client
Bad
• Only creating and
reading strings
Jackson
lör...
Where to send?
lördag 24 januari 15
public interface ContactService {
public void saveContact(Contact contact);
public List<Contact> getContacts();
}
Remote P...
public interface ContactService {
public AsyncResult<Void> saveContact(Contact contact);
public AsyncResult<List<Contact>>...
Good
• Simple but powerful
concept
• The default solution
• Optimized format
Bad
• Sending the entire
object graph
• Polym...
Most popular!
51 %
lördag 24 januari 15
Where to send
JSON?
lördag 24 januari 15
GET /contacts
DELETE /contacts/5
PUT /contacts { name: "John Doe", ... }
REST
lördag 24 januari 15
@Path("/contacts")
public interface ContactsService {
@GET
public List<Contact> listContacts();
@Path("/{id}")
@DELETE
pub...
@Path("/contacts")
public interface ContactsService extends DirectRestService {
// Same content
}
ContactsService contacts...
Good
• Any server
• Any client
Bad
• Some boilerplate
resty-gwt
lördag 24 januari 15
Real world usage
6 %
lördag 24 januari 15
Wild ideas
lördag 24 januari 15
Send interfaces
instead of objects
lördag 24 januari 15
public interface Contact {
public void setName(String name);
public String getName();
public void setYearOfBirth(int yearO...
New possibilities
Send partial updates
Manage entity identity
Use instance methods for RPC
lördag 24 januari 15
Good
• Entities do not need
to be GWT
compatible
• Combines RPC and
entity management
• Automatic request
handling
Bad
• C...
Define message
Generate code
lördag 24 januari 15
message Contact {
required string name = 1;
required int32 yearOfBirth = 2;
repeated string emailAddresses = 3;
optional A...
Good
• Any language
• Google's data
interchange format
• Backwards
compatible
Bad
• Binary format
• Not very widely
used
P...
What if we put
the server in
control?
lördag 24 januari 15
lördag 24 januari 15
public class ContactState extends SharedState {
public String name;
@DelegateToWidget
public int yearOfBirth;
}
@OnStateCh...
public interface ContactRpc extends ServerRpc {
public void deleteContact(int id);
}
// Register RPC handler on the server...
Good
• Stateful server
• Server push
Bad
• Stateful server
• Tied to the
framework
Vaadin Connectors
lördag 24 januari 15
What if we
completely hide
the transport?
lördag 24 januari 15
// Fire event
@Inject
Event<Contact> contactEvent;
public void updateContact(Contact contact) {
contactEvent.fire(contact)...
Good
• Transparent
communication
• Server push
Bad
• Transparent
communication
• Tied to the
framework
Errai Bus
lördag 24...
Questions?
Answers?
Please rate the talk at
gwtcreate.com/agenda
? leif@vaadin.com
lördag 24 januari 15
Upcoming SlideShare
Loading in …5
×

Comparing GWT Transport Mechanisms

8,108 views

Published on

Presentation about transport mechanisms in GWT, held at GWT.create 2015 in San Francisco and Munich.

Published in: Software
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
8,108
On SlideShare
0
From Embeds
0
Number of Embeds
128
Actions
Shares
0
Downloads
52
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Comparing GWT Transport Mechanisms

  1. 1. Leif Åstrand Product Manager Comparing GWT Transport Mechanisms lördag 24 januari 15
  2. 2. Transport lördag 24 januari 15
  3. 3. RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, url); try { builder.sendRequest(requestDataString, new RequestCallback() { @Override public void onResponseReceived(Request request, Response response) { int statusCode = response.getStatusCode(); String text = response.getText(); } @Override public void onError(Request request, Throwable exception) { // TODO Handle asynchronous problems } }); } catch (RequestException e) { // TODO Handle synchronous problems } RequestBuilder lördag 24 januari 15
  4. 4. Good • It just works Bad • Low level RequestBuilder lördag 24 januari 15
  5. 5. Real world usage 8 % lördag 24 januari 15
  6. 6. What to send? lördag 24 januari 15
  7. 7. public class Contact { private String name; private int yearOfBirth; private List<String> emailAddresses; private Address address; public static class Address { private String street; private String city; } // + Getters and setters } Contact lördag 24 januari 15
  8. 8. String data = contact.getName(); data += "," + contact.getYearOfBirth(); String[] parts = data.split(","); contact.setName(parts[0]); contact.setYearOfBirth(Integer.parseInt(parts[1])); String conversion lördag 24 januari 15
  9. 9. String data = contact.getName(); data += "," + contact.getYearOfBirth(); String[] parts = data.split(","); contact.setName(parts[0]); contact.setYearOfBirth(Integer.parseInt(parts[1])); String conversion lördag 24 januari 15
  10. 10. { name: "John Doe", yearOfBirth: 1900, address: { street: "Happy Street 1", city: "Turku" }, emailAddresses: ["john@doe.com", "johndoe@gmail.com"] } JSON lördag 24 januari 15
  11. 11. JSONObject json = JSONParser.parseStrict(string).isObject(); contact.setName(json.get("name").isString().stringValue()); contact.setYearOfBirth( (int) json.get("yearOfBirth").isNumber().doubleValue()); contact.setAddress( parseAddress(json.get("address").isObject())); JSONArray emailAddresses = json.get("emailAddresses").isArray(); for (int i = 0; i < emailAddresses.size(); i++) { contact.getEmailAddresses().add( emailAddresses.get(i).isString().stringValue()); } } JSONValue parsing lördag 24 januari 15
  12. 12. Good • It’s standard • Human readable format • Compact format Bad • Not completely typesafe • Boilerplate • Client only JSONValue lördag 24 januari 15
  13. 13. What about the server? lördag 24 januari 15
  14. 14. ObjectMapper mapper = new ObjectMapper(); try { Contact contact = mapper.readValue(string, Contact.class); } catch (VariousExceptions e) { // Do something sensible } Jackson on the server lördag 24 januari 15
  15. 15. Reflection Code generation lördag 24 januari 15
  16. 16. public static interface ContactMapper extends ObjectMapper<Contact> {} public Contact parseContact(String string) { ContactMapper mapper = GWT.create(ContactMapper.class); Contact contact = mapper.read(jsonString); return contact; } gwt-jackson lördag 24 januari 15
  17. 17. Good • Minimal boiler plate • Can share code between server and client Bad • Only creating and reading strings Jackson lördag 24 januari 15
  18. 18. Where to send? lördag 24 januari 15
  19. 19. public interface ContactService { public void saveContact(Contact contact); public List<Contact> getContacts(); } Remote Procedure Call lördag 24 januari 15
  20. 20. public interface ContactService { public AsyncResult<Void> saveContact(Contact contact); public AsyncResult<List<Contact>> getContacts(); } Asynchronous public interface ContactServiceAsync { public void saveContact(Contact contact, AsyncCallback<Void> callback); public void getContacts(AsyncCallback<List<Contact>> callback); } lördag 24 januari 15
  21. 21. Good • Simple but powerful concept • The default solution • Optimized format Bad • Sending the entire object graph • Polymorphism can cause huge files • Optimized format GWT-RPC lördag 24 januari 15
  22. 22. Most popular! 51 % lördag 24 januari 15
  23. 23. Where to send JSON? lördag 24 januari 15
  24. 24. GET /contacts DELETE /contacts/5 PUT /contacts { name: "John Doe", ... } REST lördag 24 januari 15
  25. 25. @Path("/contacts") public interface ContactsService { @GET public List<Contact> listContacts(); @Path("/{id}") @DELETE public void deleteContact(@PathParam("id") int id); @PUT public void createContact(Contact contact); } JAX-RS lördag 24 januari 15
  26. 26. @Path("/contacts") public interface ContactsService extends DirectRestService { // Same content } ContactsService contactsService = GWT.create(ContactsService.class); REST.withCallback(myContactListCallback). call(contactsService).listContacts(); resty-gwt lördag 24 januari 15
  27. 27. Good • Any server • Any client Bad • Some boilerplate resty-gwt lördag 24 januari 15
  28. 28. Real world usage 6 % lördag 24 januari 15
  29. 29. Wild ideas lördag 24 januari 15
  30. 30. Send interfaces instead of objects lördag 24 januari 15
  31. 31. public interface Contact { public void setName(String name); public String getName(); public void setYearOfBirth(int yearOfBirth); public int getYearOfBirth(); public void setAddress(Address address); public Address getAddress(); public void setEmailAddresses(List<String> addresses); public List<String> getEmailAddresses(); } Contact interface lördag 24 januari 15
  32. 32. New possibilities Send partial updates Manage entity identity Use instance methods for RPC lördag 24 januari 15
  33. 33. Good • Entities do not need to be GWT compatible • Combines RPC and entity management • Automatic request handling Bad • Complex setup • Heavy coupling with the server RequestFactory lördag 24 januari 15
  34. 34. Define message Generate code lördag 24 januari 15
  35. 35. message Contact { required string name = 1; required int32 yearOfBirth = 2; repeated string emailAddresses = 3; optional Address address = 4; } Contact message lördag 24 januari 15
  36. 36. Good • Any language • Google's data interchange format • Backwards compatible Bad • Binary format • Not very widely used Protocol Buffers lördag 24 januari 15
  37. 37. What if we put the server in control? lördag 24 januari 15
  38. 38. lördag 24 januari 15
  39. 39. public class ContactState extends SharedState { public String name; @DelegateToWidget public int yearOfBirth; } @OnStateChange("name") private void updateName() { doSomethingWithTheName(getState().name); } @Override protected ContactState getState() { return (ContactState) super.getState(); } State synchronization lördag 24 januari 15
  40. 40. public interface ContactRpc extends ServerRpc { public void deleteContact(int id); } // Register RPC handler on the server registerRpc(new ContactRpc() { @Override public void deleteContact(int id) { ContactDAO.deleteById(id); } }); // Send RPC from the client public void sendDelete(int contactId) { getRpcProxy(ContactRpc.class).deleteContact(contactId); } RPC lördag 24 januari 15
  41. 41. Good • Stateful server • Server push Bad • Stateful server • Tied to the framework Vaadin Connectors lördag 24 januari 15
  42. 42. What if we completely hide the transport? lördag 24 januari 15
  43. 43. // Fire event @Inject Event<Contact> contactEvent; public void updateContact(Contact contact) { contactEvent.fire(contact); } // Listen to event public void contactUpdateObserver(@Observes Contact contact) { ContactDAO.updateContact(contact); } CDI events lördag 24 januari 15
  44. 44. Good • Transparent communication • Server push Bad • Transparent communication • Tied to the framework Errai Bus lördag 24 januari 15
  45. 45. Questions? Answers? Please rate the talk at gwtcreate.com/agenda ? leif@vaadin.com lördag 24 januari 15

×