SlideShare uma empresa Scribd logo
1 de 54
Baixar para ler offline
Comparing GWT
Transport Mechanisms
Leif Åstrand
Senior Vaadin Expert

torsdag 19 december 13
Contact
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
}

torsdag 19 december 13
AJAX

torsdag 19 december 13
RequestBuilder
Good

Bad

• It just works

• Low level

torsdag 19 december 13
Real world usage

11 %
torsdag 19 december 13
RequestBuilder
RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, url);
try {
builder.sendRequest(requestData, 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
}
torsdag 19 december 13
Contact
String
torsdag 19 december 13
String conversion
String data = contact.getName();
data += "," + contact.getYearOfBirth();
String[] parts = data.split(",");
contact.setName(parts[0]);
contact.setYearOfBirth(Integer.parseInt(parts[1]));

torsdag 19 december 13
String conversion
String data = contact.getName();
data += "," + contact.getYearOfBirth();
String[] parts = data.split(",");
contact.setName(parts[0]);
contact.setYearOfBirth(Integer.parseInt(parts[1]));

torsdag 19 december 13
XML
<?xml version="1.0" encoding="UTF-8"?>
<contact name="John Doe" yearOfBirth="1900">
	 <address street="HappyStreet 1" city="Turku" />
	 <email address="john@doe.com" />
	 <email address="johndoe@gmail.com" />
</contact>

torsdag 19 december 13
XML parsing
Document document = XMLParser.parse(string);
Element contactElement = document.getDocumentElement();
contact.setName(contactElement.getAttribute("name"));
contact.setYearOfBirth(Integer.parseInt(
contactElement.getAttribute("yearOfBirth")));
contact.setAddress(parseAddress(
contactElement.getElementsByTagName("address").item(0)));
NodeList emailTags =
contactElement.getElementsByTagName("email");
for (int i = 0; i < emailTags.getLength(); i++) {
contact.getEmailAddresses().add(
((Element) emailTags.item(i))
.getAttribute("address"));
}
torsdag 19 december 13
XML
Good

Bad

• It’s “standard”
• Lots of server-side
libraries

• Verbose data
• Verbose code
• Document markup
language
• Not so common in
the GWT ecosystem
• Not typesafe

torsdag 19 december 13
JSON
{
	
	
	
	
	
	
	
}

name: "John Doe",
yearOfBirth: 1900,
address: {
	 street: "Happy Street 1",
	 city: "Turku"
},
emailAddresses: ["john@doe.com", "johndoe@gmail.com"]

torsdag 19 december 13
JSONValue parsing
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());
}
}

torsdag 19 december 13
JSON
Good

Bad

• It’s “standard”
• Extensive library
support
• Compact format

• Not completely
typesafe
• JSONValue parsing
code is verbose

torsdag 19 december 13
JavaScriptObject
public class ContactJso extends JavaScriptObject {
public native String getName() /*-{
return this["name"];
}-*/;
public native int getYearOfBirth() /*-{
return this["yearOfBirth"];
}-*/;
public native AddressJso getAddress() /*-{
return this["address"];
}-*/;
public native JsArrayString getEmailAddresses() /*-{
return this["emailAddresses"];
}-*/;
}
torsdag 19 december 13
JavaScriptObject
Good

Bad

• Very efficient
• Very little boilerplate

• /*-{ ... }-*/; syntax
• Can’t share code
with the server

torsdag 19 december 13
What about the
server?

torsdag 19 december 13
JAX-RS

torsdag 19 december 13
org.json
Good

Bad

• It’s “standard”
• Full control

• About as verbose
as JSONValue
• Not suitable for
GWT
• The Software shall
be used for Good,
not Evil.

torsdag 19 december 13
Jackson on the server
ObjectMapper mapper = new ObjectMapper();
try {
Contact contact = mapper.readValue(string, Contact.class);
} catch (VariousExceptions e) {
// Do something sensible
}

torsdag 19 december 13
Reflection
Code generation

torsdag 19 december 13
gwt-jackson
public static interface ContactMapper extends
ObjectMapper<Contact> {}
public Contact parseContact(String string) {
ContactMapper mapper = GWT.create(ContactMapper.class);
Contact contact = mapper.read(string);
return contact;
}

torsdag 19 december 13
Jackson
Good

Bad

• Minimal boiler plate
• Can share code
between server and
client
• Plugin for JAX-RS

• You’re still just
sending objects

torsdag 19 december 13
Using interfaces
instead of objects

torsdag 19 december 13
Contact interface
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();
}

torsdag 19 december 13
AutoBean
interface AddressBookFactory extends AutoBeanFactory {
public AutoBean<Contact> contact();
}
public void autobeanExample() {
AddressBookFactory factory = GWT.create(AddressBookFactory.class);
AutoBean<Contact> contactBean = factory.contact();
Contact contact = contactBean.as();
contact.setName("John Doe");
contact.setYearOfBirth(1900);
contact.setEmailAddresses(Arrays.asList("john@doe.com",
"johndoe@gmail.com"));
String json = AutoBeanCodex.encode(contactBean).getPayload();
AutoBean<Contact> bean = AutoBeanCodex.decode(factory,
Contact.class, json);
contact = bean.as();
}
torsdag 19 december 13
AutoBean
Good

Bad

• Flexible foundation
for custom
implementations of
interface methods

• Can’t use classes

torsdag 19 december 13
Intercepting interface
methods allows us to...
Use instance methods for RPC

Manage entity identity

Send partial updates

torsdag 19 december 13
RequestFactory setting it up
public interface AddressBookRequestFactory
extends RequestFactory {
public ContactRequest contactRequest();
}
@Service(Contact.class)
public interface ContactRequest extends RequestContext {
public Request<List<ContactProxy>> getContacts();
public InstanceRequest<ContactProxy, Void> update();
}
public void setupRequestFactory() {
this.factory = GWT.create(AddressBookRequestFactory.class);
this.eventBus = new SimpleEventBus();
this.factory.initialize(this.eventBus);
}
torsdag 19 december 13
RequestFactory client-side usage
public void contactRequest() {
ContactRequest contactRequest = factory.contactRequest();
contactRequest.getContacts().with("address").fire(
new Receiver<List<ContactProxy>>() {
@Override
public void onSuccess(List<ContactProxy> contacts) {
updateUI(contacts);
}
});
}
public void updateContact(ContactProxy proxy) {
ContactRequest contactRequest = factory.contactRequest();
contactRequest.update().using(proxy).fire();
}

torsdag 19 december 13
RequestFactory server-side
public class Contact {
// + fields, setters and getters
public Integer getId() {
return this.id;
}
public Integer getVersion() {
return this.version;
}
public void update() {
ContactDAO.update(this);
}
public static List<Contact> getContacts() {
return ContactDAO.fetchContacts();
}
}
torsdag 19 december 13
RequestFactory
Good

Bad

• Entities do not need
to be GWT
compatible
• Combines RPC and
entity management
• Automatic request
handling

• Complex setup
• Heavy coupling with
the server

torsdag 19 december 13
Real world usage

7%
torsdag 19 december 13
Why not just send
Java objects?

torsdag 19 december 13
Send and receive
objects
public Object[] sendAndReceive(Object[] objects);
public interface ContactService {
public void saveContact(Contact contact);
public List<Contact> getContacts();
}

torsdag 19 december 13
Asynchronousity
public interface ContactService {
public AsyncResult<Void> saveContact(Contact contact);
public AsyncResult<List<Contact>> getContacts();
}
public interface ContactServiceAsync {
public void saveContact(Contact contact,
AsyncCallback<Void> callback);
public void getContacts(AsyncCallback<List<Contact>>
callback);
}

torsdag 19 december 13
GWT-RPC
Good

Bad

• Simple but powerful
concept
• The default solution

• You (almost) always
send the entire
object graph

torsdag 19 december 13
Most popular!

53 %
torsdag 19 december 13
2 | Foo | Bar | 42 | 2 | -4

[-4, 2, 42, [“Foo”, “Bar”]]

torsdag 19 december 13
What if we put
the server in
control?

torsdag 19 december 13
torsdag 19 december 13
State
synchronization

torsdag 19 december 13
Reacting to state
changes
public class ContactState extends SharedState {
public String name;
@DelegateToWidget
public int yearOfBirth;
}
@Override
public TextButtonState getState() {
return (TextButtonState) super.getState();
}
addStateChangeHandler("name", new StateChangeHandler() {
@Override
public void onStateChanged(StateChangeEvent stateChangeEvent) {
String name = getState().name;
doSomethingWithTheName(name);
}
});

torsdag 19 december 13
Events

torsdag 19 december 13
RPC
public interface ContactRpc extends ServerRpc {
public void deleteContact(int id);
}
// Sending RPC from the client
public void sendDelete(int contactId) {
getRpcProxy(ContactRpc.class).deleteContact(contactId);
}
//Registering RPC handler on the server
registerRpc(new ContactRpc() {
@Override
public void deleteContact(int id) {
ContactDAO.deleteById(id);
}
});
torsdag 19 december 13
Vaadin
Good

Bad

• Stateful server
• Server push

• Stateful server

torsdag 19 december 13
Real world usage

6%
torsdag 19 december 13
What if we
completely hide
the transport?

torsdag 19 december 13
Local? Remote?
It’s all the same!

torsdag 19 december 13
Errai CDI events
// Fire event from the client or the server
@Inject
Event<Contact> contactEvent;
public void updateContact(Contact contact) {
contactEvent.fire(contact);
}
// Listen to event on the client or the server
public void contactUpdateObserver(@Observes Contact contact) {
ContactDAO.updateContact(contact);
}

torsdag 19 december 13
Errai Bus
Good

Bad

• Transparent
communication
• Different protocols
• Server push

• Transparent
communication

torsdag 19 december 13
Which one should
I use?

torsdag 19 december 13
?
torsdag 19 december 13

Did I get some
detail wrong?
Questions?
Please rate the talk at
gwtcreate.com/agenda

leif@vaadin.com

Mais conteúdo relacionado

Semelhante a Comparing GWT Transport Mechanisms

Semelhante a Comparing GWT Transport Mechanisms (7)

Drupal 8 configuration system for coders and site builders - Drupalaton 2013
Drupal 8 configuration system for coders and site builders - Drupalaton 2013Drupal 8 configuration system for coders and site builders - Drupalaton 2013
Drupal 8 configuration system for coders and site builders - Drupalaton 2013
 
TDC2016SP - Trilha .NET
TDC2016SP - Trilha .NETTDC2016SP - Trilha .NET
TDC2016SP - Trilha .NET
 
Drupal 8 configuration system for coders and site builders - DrupalCamp Balti...
Drupal 8 configuration system for coders and site builders - DrupalCamp Balti...Drupal 8 configuration system for coders and site builders - DrupalCamp Balti...
Drupal 8 configuration system for coders and site builders - DrupalCamp Balti...
 
Introduction à Dart
Introduction à DartIntroduction à Dart
Introduction à Dart
 
Rust vs. Go: qual è il linguaggio più adatto al tuo progetto?
Rust vs. Go: qual è il linguaggio più adatto al tuo progetto?Rust vs. Go: qual è il linguaggio più adatto al tuo progetto?
Rust vs. Go: qual è il linguaggio più adatto al tuo progetto?
 
Java 8 to the rescue!?
Java 8 to the rescue!?Java 8 to the rescue!?
Java 8 to the rescue!?
 
Why realm?
Why realm?Why realm?
Why realm?
 

Último

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Victor Rentea
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 

Último (20)

Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptx
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 

Comparing GWT Transport Mechanisms

  • 1. Comparing GWT Transport Mechanisms Leif Åstrand Senior Vaadin Expert torsdag 19 december 13
  • 2. Contact 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 } torsdag 19 december 13
  • 4. RequestBuilder Good Bad • It just works • Low level torsdag 19 december 13
  • 5. Real world usage 11 % torsdag 19 december 13
  • 6. RequestBuilder RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, url); try { builder.sendRequest(requestData, 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 } torsdag 19 december 13
  • 8. String conversion String data = contact.getName(); data += "," + contact.getYearOfBirth(); String[] parts = data.split(","); contact.setName(parts[0]); contact.setYearOfBirth(Integer.parseInt(parts[1])); torsdag 19 december 13
  • 9. String conversion String data = contact.getName(); data += "," + contact.getYearOfBirth(); String[] parts = data.split(","); contact.setName(parts[0]); contact.setYearOfBirth(Integer.parseInt(parts[1])); torsdag 19 december 13
  • 10. XML <?xml version="1.0" encoding="UTF-8"?> <contact name="John Doe" yearOfBirth="1900"> <address street="HappyStreet 1" city="Turku" /> <email address="john@doe.com" /> <email address="johndoe@gmail.com" /> </contact> torsdag 19 december 13
  • 11. XML parsing Document document = XMLParser.parse(string); Element contactElement = document.getDocumentElement(); contact.setName(contactElement.getAttribute("name")); contact.setYearOfBirth(Integer.parseInt( contactElement.getAttribute("yearOfBirth"))); contact.setAddress(parseAddress( contactElement.getElementsByTagName("address").item(0))); NodeList emailTags = contactElement.getElementsByTagName("email"); for (int i = 0; i < emailTags.getLength(); i++) { contact.getEmailAddresses().add( ((Element) emailTags.item(i)) .getAttribute("address")); } torsdag 19 december 13
  • 12. XML Good Bad • It’s “standard” • Lots of server-side libraries • Verbose data • Verbose code • Document markup language • Not so common in the GWT ecosystem • Not typesafe torsdag 19 december 13
  • 13. JSON { } name: "John Doe", yearOfBirth: 1900, address: { street: "Happy Street 1", city: "Turku" }, emailAddresses: ["john@doe.com", "johndoe@gmail.com"] torsdag 19 december 13
  • 14. JSONValue parsing 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()); } } torsdag 19 december 13
  • 15. JSON Good Bad • It’s “standard” • Extensive library support • Compact format • Not completely typesafe • JSONValue parsing code is verbose torsdag 19 december 13
  • 16. JavaScriptObject public class ContactJso extends JavaScriptObject { public native String getName() /*-{ return this["name"]; }-*/; public native int getYearOfBirth() /*-{ return this["yearOfBirth"]; }-*/; public native AddressJso getAddress() /*-{ return this["address"]; }-*/; public native JsArrayString getEmailAddresses() /*-{ return this["emailAddresses"]; }-*/; } torsdag 19 december 13
  • 17. JavaScriptObject Good Bad • Very efficient • Very little boilerplate • /*-{ ... }-*/; syntax • Can’t share code with the server torsdag 19 december 13
  • 20. org.json Good Bad • It’s “standard” • Full control • About as verbose as JSONValue • Not suitable for GWT • The Software shall be used for Good, not Evil. torsdag 19 december 13
  • 21. Jackson on the server ObjectMapper mapper = new ObjectMapper(); try { Contact contact = mapper.readValue(string, Contact.class); } catch (VariousExceptions e) { // Do something sensible } torsdag 19 december 13
  • 23. gwt-jackson public static interface ContactMapper extends ObjectMapper<Contact> {} public Contact parseContact(String string) { ContactMapper mapper = GWT.create(ContactMapper.class); Contact contact = mapper.read(string); return contact; } torsdag 19 december 13
  • 24. Jackson Good Bad • Minimal boiler plate • Can share code between server and client • Plugin for JAX-RS • You’re still just sending objects torsdag 19 december 13
  • 25. Using interfaces instead of objects torsdag 19 december 13
  • 26. Contact interface 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(); } torsdag 19 december 13
  • 27. AutoBean interface AddressBookFactory extends AutoBeanFactory { public AutoBean<Contact> contact(); } public void autobeanExample() { AddressBookFactory factory = GWT.create(AddressBookFactory.class); AutoBean<Contact> contactBean = factory.contact(); Contact contact = contactBean.as(); contact.setName("John Doe"); contact.setYearOfBirth(1900); contact.setEmailAddresses(Arrays.asList("john@doe.com", "johndoe@gmail.com")); String json = AutoBeanCodex.encode(contactBean).getPayload(); AutoBean<Contact> bean = AutoBeanCodex.decode(factory, Contact.class, json); contact = bean.as(); } torsdag 19 december 13
  • 28. AutoBean Good Bad • Flexible foundation for custom implementations of interface methods • Can’t use classes torsdag 19 december 13
  • 29. Intercepting interface methods allows us to... Use instance methods for RPC Manage entity identity Send partial updates torsdag 19 december 13
  • 30. RequestFactory setting it up public interface AddressBookRequestFactory extends RequestFactory { public ContactRequest contactRequest(); } @Service(Contact.class) public interface ContactRequest extends RequestContext { public Request<List<ContactProxy>> getContacts(); public InstanceRequest<ContactProxy, Void> update(); } public void setupRequestFactory() { this.factory = GWT.create(AddressBookRequestFactory.class); this.eventBus = new SimpleEventBus(); this.factory.initialize(this.eventBus); } torsdag 19 december 13
  • 31. RequestFactory client-side usage public void contactRequest() { ContactRequest contactRequest = factory.contactRequest(); contactRequest.getContacts().with("address").fire( new Receiver<List<ContactProxy>>() { @Override public void onSuccess(List<ContactProxy> contacts) { updateUI(contacts); } }); } public void updateContact(ContactProxy proxy) { ContactRequest contactRequest = factory.contactRequest(); contactRequest.update().using(proxy).fire(); } torsdag 19 december 13
  • 32. RequestFactory server-side public class Contact { // + fields, setters and getters public Integer getId() { return this.id; } public Integer getVersion() { return this.version; } public void update() { ContactDAO.update(this); } public static List<Contact> getContacts() { return ContactDAO.fetchContacts(); } } torsdag 19 december 13
  • 33. RequestFactory Good Bad • Entities do not need to be GWT compatible • Combines RPC and entity management • Automatic request handling • Complex setup • Heavy coupling with the server torsdag 19 december 13
  • 34. Real world usage 7% torsdag 19 december 13
  • 35. Why not just send Java objects? torsdag 19 december 13
  • 36. Send and receive objects public Object[] sendAndReceive(Object[] objects); public interface ContactService { public void saveContact(Contact contact); public List<Contact> getContacts(); } torsdag 19 december 13
  • 37. Asynchronousity public interface ContactService { public AsyncResult<Void> saveContact(Contact contact); public AsyncResult<List<Contact>> getContacts(); } public interface ContactServiceAsync { public void saveContact(Contact contact, AsyncCallback<Void> callback); public void getContacts(AsyncCallback<List<Contact>> callback); } torsdag 19 december 13
  • 38. GWT-RPC Good Bad • Simple but powerful concept • The default solution • You (almost) always send the entire object graph torsdag 19 december 13
  • 39. Most popular! 53 % torsdag 19 december 13
  • 40. 2 | Foo | Bar | 42 | 2 | -4 [-4, 2, 42, [“Foo”, “Bar”]] torsdag 19 december 13
  • 41. What if we put the server in control? torsdag 19 december 13
  • 44. Reacting to state changes public class ContactState extends SharedState { public String name; @DelegateToWidget public int yearOfBirth; } @Override public TextButtonState getState() { return (TextButtonState) super.getState(); } addStateChangeHandler("name", new StateChangeHandler() { @Override public void onStateChanged(StateChangeEvent stateChangeEvent) { String name = getState().name; doSomethingWithTheName(name); } }); torsdag 19 december 13
  • 46. RPC public interface ContactRpc extends ServerRpc { public void deleteContact(int id); } // Sending RPC from the client public void sendDelete(int contactId) { getRpcProxy(ContactRpc.class).deleteContact(contactId); } //Registering RPC handler on the server registerRpc(new ContactRpc() { @Override public void deleteContact(int id) { ContactDAO.deleteById(id); } }); torsdag 19 december 13
  • 47. Vaadin Good Bad • Stateful server • Server push • Stateful server torsdag 19 december 13
  • 48. Real world usage 6% torsdag 19 december 13
  • 49. What if we completely hide the transport? torsdag 19 december 13
  • 50. Local? Remote? It’s all the same! torsdag 19 december 13
  • 51. Errai CDI events // Fire event from the client or the server @Inject Event<Contact> contactEvent; public void updateContact(Contact contact) { contactEvent.fire(contact); } // Listen to event on the client or the server public void contactUpdateObserver(@Observes Contact contact) { ContactDAO.updateContact(contact); } torsdag 19 december 13
  • 52. Errai Bus Good Bad • Transparent communication • Different protocols • Server push • Transparent communication torsdag 19 december 13
  • 53. Which one should I use? torsdag 19 december 13
  • 54. ? torsdag 19 december 13 Did I get some detail wrong? Questions? Please rate the talk at gwtcreate.com/agenda leif@vaadin.com