Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Put your systems to REST       Guilherme Silveira       @guilhermecaelum
Guilherme Silveira                  guilherme.silveira@caelum.com.br2002   guj.com.br2003   vraptor2004   caelum.com.br200...
banco.com    calendario.comviagem.com   empresa.com
CORBAparaíso?
EJBparaíso?
SOAPparaíso?
o que é REST?
qual o futuro da integração na      web?
representação de uma viagem<?xml version="1.0" encoding="UTF-8" standalum="yes"?><flight>  <information>    <from>sao paul...
service locator ao integrar:                     acoplamento++                           unrest                           ...
service locator ao integrar:                     acoplamento++                           unrest                           ...
representação em REST<?xml version="1.0" encoding="UTF-8" standalum="yes"?><flight>  <information>    <from>sao paulo</fro...
Rest Client: hipermídiaflight = Client.at(http://resttrips.com/f/574XR4).get();confirmation = flight.getLink("payment").  ...
alterando o serviço<?xml version="1.0" encoding="UTF-8" standalum="yes"?><flight>  <information>    <from>sao paulo</from>...
dependency injection em integração:                        acoplamento--                            restrips              ...
dependency injection em integração:                        acoplamento--                            restrips              ...
trip = recurso        http://kayak.com/f/574XR4payment = recurso        any_uri_unknown_at_compile_time
eu nunca viajo sozinho
meu amigo  ricky
Rest Client: compartilhando uma viagemflight = Client.at(http://resttrips.com/f/574XR4).get();confirmation = flight.getLin...
Rest Client: compartilhando uma viagemflight = Client.at(http://resttrips.com/f/574XR4).get();confirmation = flight.getLin...
Rest Client: compartilhando uma viagemflight = Client.at(http://resttrips.com/f/574XR4).get();confirmation = flight.getLin...
calendar: integrando sistemasmyself = Client.at(http://users.calendar.com)                                .with(auth).get(...
calendar: integrando sistemasmyself = Client.at(http://users.calendar.com)                                .with(auth).get(...
calendar: outros exemplosme.link("calendar").patch(representacao_aniversarios)me.link("calendar").patch(represetancao_hotel)
e daí?
e daí?Atualizações na viagem ==> refletem aquiAtualizações no hotel ==> refletem aquiAtualizações no encontro ==> refletem...
e daí?                          gre!                      nte                 e ,i              us         n ãoAtualizaçõe...
o que mais?
o que mais?Remove ==> Cancela a viagemRemove ==> Cancela o hotelRemove ==> Email para colegas
o que mais?                                   liz e!                              nt ra                          esce     ...
mas qual o formato dopagamento ou calendário?
#json, #xml,#soap #etc?
qual #json, #xml      #etc?
exercise
quem é este?
quem é essa?
fácil? e ela?
fácil? e ela?                       lh a!                      fi                in ha          é m   n ão
conteúdo sem semântica    não tem valor!
qual “formato”?
qual “formato”?micro formats, media types, rdf etc
qual “formato”?                              nk s!                         er li                      hyp               ts...
integração na web
Put your server to REST    leonard richardsons model
Server Maturity              1 uri, 1 http verb/services.do?action=install&...
Server Maturity                  1 uri, 1 http verb/services.do?action=install&...@Path("/services")public class Services ...
Server Maturity                1 uri, 1 http verbpublic class InstallService {  public Response execute() {    return Resp...
But?
1 uri, 1 http verb/services.do?action=install&... I know them all beforehand.
1 uri, 1 http verb/services.do?action=install&...Any change will break all our clients!
a priori knowledge
a priori knowledge        =
a priori knowledge        =    coupling++
Server Maturity           Multiple uris, 1 http verb/install?...
Server Maturity             Multiple uris, 1 http verb/install?... @Path("/services") public class Services {   @GET @Path...
but...
GET hellGET should not imply in  undesireable effects
POST hellGET could help us with        cache!
Server Maturity  Multiple uris, multiple verbs         POST /cloud GET /cloud/1547437/softwarePOST /cloud/1547437/software
rails + restfulie  rubyonrails.org
rails + restfulie                   rubyonrails.orgclass SoftwaresController < ApplicationController    acts_as_restfulie ...
JAX-RS@Path("/softwares")public class SoftwareResource {  @POST @Consumes("application/xml")  public Response install(Soft...
JAX-RS  @DELETE @Path("{id}")  public Response uninstall(@PathParam("id") Long id) {    Software software = SoftwareReposi...
Uniform Interface++   Resources++
Http verbs examplePOST createsPUT replacesPATCH updatesDELETE removesGET retrievesOPTIONS tells me what i can do...
Is a Restful service   a cute CRUD?
yes
but there is more!
@XmlRootElement@XmlType(propOrder= {"id", "host", "softwares", "links"})public class Machine {  private final all variable...
@XmlRootElement@XmlType(propOrder= {"id", "host", "softwares", "links"})public class Machine {  private final all variable...
@Path("/machines")public class MachineResource {        MachineResource  @Path("{id}/softwares")  public SoftwareResource ...
@Path("/machines")public class MachineResource {        MachineResource  @Path("{id}/softwares")  public SoftwareResource ...
Server Modelaccording toLeonard Richardson, 2008                           one uri + one verb
Server Modelaccording toLeonard Richardson, 2008                               Ugly                           one uri + on...
Server Modelaccording toLeonard Richardson, 2008                           multiple                            uris       ...
Server Modelaccording toLeonard Richardson, 2008                                      Less ugly                           ...
Server Modelaccording toLeonard Richardson, 2008                                       multiple                           ...
Server Modelaccording toLeonard Richardson, 2008                           cute CRUD                                      ...
Server Model                      restaccording toLeonard Richardson, 2008        hypermedia                              ...
JAX-RS 2 wishlist
guj
vraptor 0, 2, 3
java keynotes
exemplosvraptor.org
1. repetições?@Path("/services")public class Services {  @GET  public Response services(    @QueryParam("action") String a...
você quer fazer copy+paste?
repetir = inferno
Convention over Configuration@Resourcepublic class Services {		 private final ServiceFactory factory;		 public Services(Ser...
yes!
yes!
2. TDD: hard to test@Path("/products")public class Products {                                   coupled to the  @GET      ...
3. Content negotiation na unha@Path("/softwares")public class SoftwareResource {  @POST @Consumes("application/xml")  publ...
4. URI coupling                                   writing the URI once...  @GET @Path("/softwares/{id}")  public Response ...
4. URI coupling                                  writing the URI again                                       several times...
4. URI coupling                                            code@Path("/softwares")public class SoftwareResource {  @POST @...
repetir = inferno
5. Parameter list@Path("/machines")public class MachineResource {  @Path("{id}/softwares")  public SoftwareResource softwa...
repetir = inferno
java         =string oriented?
java          =annotation oriented?
Cliente REST
Response response = client.at    ("http://localhost:9998/user/574").get();        6. Client internal DSLs
Response response = client.at    ("http://localhost:9998/user/574").get();User user = response.getResource();System.out.pr...
User user = response.getResource();System.out.println("user: " + user.getName());Link link = resource(user).getLink("machi...
Link link = resource(user).getLink("machine");response = link.follow().post(new Machine());double amount = resource(user)....
double amount = resource(user).refresh().                                        getAmountDue();link = resource(user).getL...
link = resource(user).getLink("payment");Payment payment = new Payment(amount);response = link.follow().post(payment);Syst...
link = resource(user).getLink("payment");Payment payment = new Payment(amount);response = link.follow().post(payment);Syst...
bottom up  design by committe      mime type    microformato
hypermídiaviabilizando a integração através da web
vraptor mvc based REST
Arun Gupta   jersey vraptor 3
vraptor somos nozes
@guilhermecaelumobrigado
Crie seu sistema REST com JAX-RS e o futuro
Crie seu sistema REST com JAX-RS e o futuro
Crie seu sistema REST com JAX-RS e o futuro
Crie seu sistema REST com JAX-RS e o futuro
Upcoming SlideShare
Loading in …5
×

Crie seu sistema REST com JAX-RS e o futuro

3,797 views

Published on

Palestra de Guilherme Silveira durante o Javaone Brazil no keynote hall.

Published in: Technology
  • Be the first to comment

Crie seu sistema REST com JAX-RS e o futuro

  1. 1. Put your systems to REST Guilherme Silveira @guilhermecaelum
  2. 2. Guilherme Silveira guilherme.silveira@caelum.com.br2002 guj.com.br2003 vraptor2004 caelum.com.br2009 restfulie2010 tectura.com.br
  3. 3. banco.com calendario.comviagem.com empresa.com
  4. 4. CORBAparaíso?
  5. 5. EJBparaíso?
  6. 6. SOAPparaíso?
  7. 7. o que é REST?
  8. 8. qual o futuro da integração na web?
  9. 9. representação de uma viagem<?xml version="1.0" encoding="UTF-8" standalum="yes"?><flight> <information> <from>sao paulo</from> <to>seoul</to> </information>  <value>900.00</value></flight>
  10. 10. service locator ao integrar: acoplamento++ unrest pay unresttrips.comguilherme
  11. 11. service locator ao integrar: acoplamento++ unrest pay unresttrips.comguilherme
  12. 12. representação em REST<?xml version="1.0" encoding="UTF-8" standalum="yes"?><flight> <information> <from>sao paulo</from> <to>seoul</to> </information>  <value>900.00</value> <link rel="payment" href="http://resttrips.com/payment/custom"/</flight>
  13. 13. Rest Client: hipermídiaflight = Client.at(http://resttrips.com/f/574XR4).get();confirmation = flight.getLink("payment"). patch(cardInformation, value);
  14. 14. alterando o serviço<?xml version="1.0" encoding="UTF-8" standalum="yes"?><flight> <information> <from>sao paulo</from> <to>seoul</to> </information>  <value>900.00</value> <link rel="payment" href="http://paysite.com/custom"/></flight>
  15. 15. dependency injection em integração: acoplamento-- restrips pay resttrips.com guilherme paysite.com
  16. 16. dependency injection em integração: acoplamento-- restrips pay resttrips.com guilherme paysite.com
  17. 17. trip = recurso http://kayak.com/f/574XR4payment = recurso any_uri_unknown_at_compile_time
  18. 18. eu nunca viajo sozinho
  19. 19. meu amigo ricky
  20. 20. Rest Client: compartilhando uma viagemflight = Client.at(http://resttrips.com/f/574XR4).get();confirmation = flight.getLink("payment"). patch(cardInformation, value/2);// send the payment link to another part of the webflight = Client.at(http://resttrips.com/f/574XR4).get();confirmation = flight.getLink("payment"). patch(cardInformation, value/2);
  21. 21. Rest Client: compartilhando uma viagemflight = Client.at(http://resttrips.com/f/574XR4).get();confirmation = flight.getLink("payment"). patch(cardInformation, value/2);// send the payment link to another part of the webflight = Client.at(http://resttrips.com/f/574XR4).get();confirmation = flight.getLink("payment"). patch(cardInformation, value/2);
  22. 22. Rest Client: compartilhando uma viagemflight = Client.at(http://resttrips.com/f/574XR4).get();confirmation = flight.getLink("payment"). patch(cardInformation, value/2);// send the payment link to another part of the webflight = Client.at(http://resttrips.com/f/574XR4).get();confirmation = flight.getLink("payment"). patch(cardInformation, value/2);
  23. 23. calendar: integrando sistemasmyself = Client.at(http://users.calendar.com) .with(auth).get();myself.link("calendar").patch(flight.link("self"));
  24. 24. calendar: integrando sistemasmyself = Client.at(http://users.calendar.com) .with(auth).get();myself.link("calendar").patch(flight.link("self"));
  25. 25. calendar: outros exemplosme.link("calendar").patch(representacao_aniversarios)me.link("calendar").patch(represetancao_hotel)
  26. 26. e daí?
  27. 27. e daí?Atualizações na viagem ==> refletem aquiAtualizações no hotel ==> refletem aquiAtualizações no encontro ==> refletem aqui
  28. 28. e daí? gre! nte e ,i us n ãoAtualizações na viagem ==> refletem aquiAtualizações no hotel ==> refletem aquiAtualizações no encontro ==> refletem aqui
  29. 29. o que mais?
  30. 30. o que mais?Remove ==> Cancela a viagemRemove ==> Cancela o hotelRemove ==> Email para colegas
  31. 31. o que mais? liz e! nt ra esce e, d s tr rq ue o n ãoRemove ==> Cancela a viagemRemove ==> Cancela o hotelRemove ==> Email para colegas
  32. 32. mas qual o formato dopagamento ou calendário?
  33. 33. #json, #xml,#soap #etc?
  34. 34. qual #json, #xml #etc?
  35. 35. exercise
  36. 36. quem é este?
  37. 37. quem é essa?
  38. 38. fácil? e ela?
  39. 39. fácil? e ela? lh a! fi in ha é m n ão
  40. 40. conteúdo sem semântica não tem valor!
  41. 41. qual “formato”?
  42. 42. qual “formato”?micro formats, media types, rdf etc
  43. 43. qual “formato”? nk s! er li hyp ts e a fo rm icro mmicro formats, media types, rdf etc
  44. 44. integração na web
  45. 45. Put your server to REST leonard richardsons model
  46. 46. Server Maturity 1 uri, 1 http verb/services.do?action=install&...
  47. 47. Server Maturity 1 uri, 1 http verb/services.do?action=install&...@Path("/services")public class Services {  @GET  public Response services(    @QueryParam("action") String action) {    ServiceFactory factory = new ServiceFactory();    Service service = factory.getServiceFor(action);    return service.execute();  }}
  48. 48. Server Maturity 1 uri, 1 http verbpublic class InstallService {  public Response execute() {    return Response.ok()             .type("application/xml")             .entity("<service>...</service>")             .build();  }}
  49. 49. But?
  50. 50. 1 uri, 1 http verb/services.do?action=install&... I know them all beforehand.
  51. 51. 1 uri, 1 http verb/services.do?action=install&...Any change will break all our clients!
  52. 52. a priori knowledge
  53. 53. a priori knowledge =
  54. 54. a priori knowledge = coupling++
  55. 55. Server Maturity Multiple uris, 1 http verb/install?...
  56. 56. Server Maturity Multiple uris, 1 http verb/install?... @Path("/services") public class Services {   @GET @Path("install")   public Response install() {     return new InstallService().execute();   }   @GET @Path("uninstall")   public Response uninstall() {     return new UninstallService().execute();   }
  57. 57. but...
  58. 58. GET hellGET should not imply in undesireable effects
  59. 59. POST hellGET could help us with cache!
  60. 60. Server Maturity Multiple uris, multiple verbs POST /cloud GET /cloud/1547437/softwarePOST /cloud/1547437/software
  61. 61. rails + restfulie rubyonrails.org
  62. 62. rails + restfulie rubyonrails.orgclass SoftwaresController < ApplicationController    acts_as_restfulie  respond_to :xml, :json    def create    @item = Item.create(params[:item])    respond_with @item, :status => :created  end    def show    @item = Item.find(params[:id])    respond_with @item  endend
  63. 63. JAX-RS@Path("/softwares")public class SoftwareResource {  @POST @Consumes("application/xml")  public Response install(Software software) {    software = SoftwareRepository.register(software);    long id = software.getId();    URI uri = UriBuilder.fromPath("/softwares/" + id)                                       .build();    software.install();    return Response.created(uri).build();  }
  64. 64. JAX-RS  @DELETE @Path("{id}")  public Response uninstall(@PathParam("id") Long id) {    Software software = SoftwareRepository.retrieve(id);    software.uninstall();    return Response.ok().build();  }
  65. 65. Uniform Interface++ Resources++
  66. 66. Http verbs examplePOST createsPUT replacesPATCH updatesDELETE removesGET retrievesOPTIONS tells me what i can do...
  67. 67. Is a Restful service a cute CRUD?
  68. 68. yes
  69. 69. but there is more!
  70. 70. @XmlRootElement@XmlType(propOrder= {"id", "host", "softwares", "links"})public class Machine {  private final all variables here;  @XmlElement(name="link", namespace="http://www.w3.org/2005/Atom")  public List<Link> getLinks() {    return Arrays.asList(      Link.to("/machines/" + getId(), "self"),      Link.to("/machines/" + getId() + "/softwares", "softwares")    );  }  @XmlElementWrapper(name="softwares")  @XmlElement(name="software")  public List<Software> getSoftwares() {    return softwares;  }  public void install(Software software) {    getSoftwares().add(software);  }  public void uninstall(Software software) {    getSoftwares().remove(software);  }} Machine.java
  71. 71. @XmlRootElement@XmlType(propOrder= {"id", "host", "softwares", "links"})public class Machine {  private final all variables here;  @XmlElement(name="link", namespace="http://www.w3.org/2005/Atom")  public List<Link> getLinks() {    return Arrays.asList(      Link.to("/machines/" + getId(), "self"),      Link.to("/machines/" + getId() + "/softwares", "softwares")    );  }  @XmlElementWrapper(name="softwares")  @XmlElement(name="software")  public List<Software> getSoftwares() {    return softwares;  }  public void install(Software software) {    getSoftwares().add(software);  }  public void uninstall(Software software) {    getSoftwares().remove(software);  }} Machine.java
  72. 72. @Path("/machines")public class MachineResource { MachineResource @Path("{id}/softwares") public SoftwareResource softwares(@PathParam("id") Long id) { Machine machine = new MachineRepository().retrieve(id); if (machine != null) { SoftwareResource softwareResource = new SoftwareResource(); softwareResource.setMachine(machine); return softwareResource; } throw new WebApplicationException(404); } @POST @Consumes("application/xml") public Response create(Machine machine) { Long id = new MachineRepository().save(machine); return Response.created(UriBuilder.fromPath("/" + id).build()).build(); } @GET @Path("{id}") @Produces("application/xml") public Machine show(@PathParam("id") Long id) { return new MachineRepository().retrieve(id); } @GET @Produces("application/xml") public Machines list() { Machines machines = new Machines(); machines.setMachine(new MachineRepository().list()); return machines;
  73. 73. @Path("/machines")public class MachineResource { MachineResource @Path("{id}/softwares") public SoftwareResource softwares(@PathParam("id") Long id) { Machine machine = new MachineRepository().retrieve(id); if (machine != null) { SoftwareResource softwareResource = new SoftwareResource(); softwareResource.setMachine(machine); return softwareResource; } throw new WebApplicationException(404); } @POST @Consumes("application/xml") public Response create(Machine machine) { Long id = new MachineRepository().save(machine); return Response.created(UriBuilder.fromPath("/" + id).build()).build(); } @GET @Path("{id}") @Produces("application/xml") public Machine show(@PathParam("id") Long id) { return new MachineRepository().retrieve(id); } @GET @Produces("application/xml") public Machines list() { Machines machines = new Machines(); machines.setMachine(new MachineRepository().list()); return machines;
  74. 74. Server Modelaccording toLeonard Richardson, 2008 one uri + one verb
  75. 75. Server Modelaccording toLeonard Richardson, 2008 Ugly one uri + one verb
  76. 76. Server Modelaccording toLeonard Richardson, 2008 multiple uris one uri + one verb
  77. 77. Server Modelaccording toLeonard Richardson, 2008 Less ugly multiple uris one uri + one verb
  78. 78. Server Modelaccording toLeonard Richardson, 2008 multiple verbs multiple uris one uri + one verb
  79. 79. Server Modelaccording toLeonard Richardson, 2008 cute CRUD multiple verbs multiple uris one uri + one verb
  80. 80. Server Model restaccording toLeonard Richardson, 2008 hypermedia multiple verbs multiple uris one uri + one verb
  81. 81. JAX-RS 2 wishlist
  82. 82. guj
  83. 83. vraptor 0, 2, 3
  84. 84. java keynotes
  85. 85. exemplosvraptor.org
  86. 86. 1. repetições?@Path("/services")public class Services {  @GET  public Response services(    @QueryParam("action") String action) {    ServiceFactory factory = new ServiceFactory();    Service service = factory.getServiceFor(action);    return service.execute();  }}
  87. 87. você quer fazer copy+paste?
  88. 88. repetir = inferno
  89. 89. Convention over Configuration@Resourcepublic class Services { private final ServiceFactory factory; public Services(ServiceFactory factory) { this.factory = factory; } public void services(String action) { factory.getServiceFor(action).execute(); }}
  90. 90. yes!
  91. 91. yes!
  92. 92. 2. TDD: hard to test@Path("/products")public class Products { coupled to the  @GET implementation  public Response create(    @QueryParam("what") String what) {    // persists    return Response.ok()             .type("application/xml")             .entity("<product>...</product>")             .build();  }}
  93. 93. 3. Content negotiation na unha@Path("/softwares")public class SoftwareResource {  @POST @Consumes("application/xml")  public Response install(Software software) {    software = SoftwareRepository.register(software);    long id = software.getId();    URI uri = UriBuilder.fromPath("/softwares/" + id)                                       .build(); software.install();    return Response.created(uri).build();  }
  94. 94. 4. URI coupling writing the URI once...  @GET @Path("/softwares/{id}")  public Response install(@QueryParam("id") Softwaresoftware) { // ...  }
  95. 95. 4. URI coupling writing the URI again several times@Path("/softwares")public class SoftwareResource {  @POST @Consumes("application/xml")  public Response install(Software software) {    software = SoftwareRepository.register(software);    long id = software.getId();    URI uri = UriBuilder.fromPath("/softwares/" + id)                                       .build(); software.install();    return Response.created(uri).build();  }
  96. 96. 4. URI coupling code@Path("/softwares")public class SoftwareResource {  @POST @Consumes("application/xml")  public Response install(Software software) {    software = SoftwareRepository.register(software);    long id = software.getId();    URI uri = UriBuilder.fromPath("/softwares/" + id)                                       .build(); software.install();    return Response.created(uri).build();  }
  97. 97. repetir = inferno
  98. 98. 5. Parameter list@Path("/machines")public class MachineResource { @Path("{id}/softwares") public SoftwareResource softwares(@PathParam("id") Long id) { Machine machine = new MachineRepository().retrieve(id); if (machine == null) { throw new WebApplicationException(404); } // ... }}
  99. 99. repetir = inferno
  100. 100. java =string oriented?
  101. 101. java =annotation oriented?
  102. 102. Cliente REST
  103. 103. Response response = client.at ("http://localhost:9998/user/574").get(); 6. Client internal DSLs
  104. 104. Response response = client.at ("http://localhost:9998/user/574").get();User user = response.getResource();System.out.println("user: " + user.getName()); 6. Client internal DSLs
  105. 105. User user = response.getResource();System.out.println("user: " + user.getName());Link link = resource(user).getLink("machine");response = link.follow().post(new Machine());
  106. 106. Link link = resource(user).getLink("machine");response = link.follow().post(new Machine());double amount = resource(user).refresh(). getAmountDue();
  107. 107. double amount = resource(user).refresh(). getAmountDue();link = resource(user).getLink("payment");Payment payment = new Payment(amount);response = link.follow().post(payment);
  108. 108. link = resource(user).getLink("payment");Payment payment = new Payment(amount);response = link.follow().post(payment);System.out.println("payment completed");
  109. 109. link = resource(user).getLink("payment");Payment payment = new Payment(amount);response = link.follow().post(payment);System.out.println("payment completed"); uma DSL alto nívelcom suporte a hipermídia
  110. 110. bottom up design by committe mime type microformato
  111. 111. hypermídiaviabilizando a integração através da web
  112. 112. vraptor mvc based REST
  113. 113. Arun Gupta jersey vraptor 3
  114. 114. vraptor somos nozes
  115. 115. @guilhermecaelumobrigado

×