Arquitetura: chega de
      mesmice
      Guilherme Silveira
Guilherme Silveira
guilherme.silveira@caelum.com.br
são paulo
são paulo
são paulo
são paulo
são paulo
Guilherme Silveira
               guilherme.silveira@caelum.com.br




2002 guj.com.br
2003 vraptor
2004 caelum.com.br
   ...
bank.com     calendar.com




travel.com   company.com
CORBA
heaven?
EJB
heaven?
SOAP
heaven?
what is REST?
what is the future
 of integration
 over the web?
what was REST?
Restful Web


              Services
Restful Web

create a saas account

                        Services
Restful Web

create a saas account


   freeze account
                        Services
Restful Web

create a saas account


   freeze account
                        Services

 reactivate account
Web




Restful         Services
Web
          http




Restful          Services
Web
           http

          port 80




Restful             Services
Web
           http

          port 80


      firewall heaven


Restful             Services
Web Services


Restful
Web Services

             xml, json
Restful
Web Services

              xml, json
Restful
             get, post, ...
Restful Web Services
          as of 2009




  But what about Hypermidia?
    What about consumers?
Restful Web Services
          as of 2009




  But what about Hypermidia?
    What about consumers?
   There is much more!
unresttrips.com: flight details



<?xml version="1.0" encoding="UTF-8" standalum="yes"?>
<flight>
  <information>
    <fro...
service locator when integrating:
                         coupling++

                            unrest
                ...
service locator when integrating:
                         coupling++

                            unrest
                ...
resttrips.com: flight details



<?xml version="1.0" encoding="UTF-8" standalum="yes"?>
<flight>
  <information>
    <from>...
resttrips.com: flight details



<?xml version="1.0" encoding="UTF-8" standalum="yes"?>
<flight>
  <information>
    <from>...
resttrips.com: making the payment




flight = Client.at('http://resttrips.com/f/574XR4').get();

confirmation = flight.ge...
resttrips.com: making the payment




flight = Client.at('http://resttrips.com/f/574XR4').get();

confirmation = flight.ge...
resttrips.com: changing its payment provider


<?xml version="1.0" encoding="UTF-8" standalum="yes"?>
<flight>
  <informat...
resttrips.com: changing its payment provider


<?xml version="1.0" encoding="UTF-8" standalum="yes"?>
<flight>
  <informat...
dependency injection when integrating:

                             coupling--

                              restrips
  ...
dependency injection when integrating:

                             coupling--

                              restrips
  ...
trip = resource
        http://kayak.com/f/574XR4




payment = resource
        any_uri_unknown_at_compile_time
não viajo sozinho
meu amigo
@sergio_caelum
meu amigo
@sergio_caelum




 Bilu bilu
resttrips.com: sharing a trip


flight = Client.at('http://resttrips.com/f/574XR4').get();

confirmation = flight.getLink(...
resttrips.com: sharing a trip


flight = Client.at('http://resttrips.com/f/574XR4').get();

confirmation = flight.getLink(...
resttrips.com: sharing a trip


flight = Client.at('http://resttrips.com/f/574XR4').get();

confirmation = flight.getLink(...
resttrips.com: sharing a trip


flight = Client.at('http://resttrips.com/f/574XR4').get();

confirmation = flight.getLink(...
calendar: integrating my systems


myself = Client.at('http://users.calendar.com')
                                .with(a...
calendar: integrating my systems


myself = Client.at('http://users.calendar.com')
                                .with(a...
calendar: more examples



me.link("calendar").patch(link_to_birthday_list)
me.link("calendar").patch(link_to_hotel_reserv...
so what?
so what?




Any update on the flight ==> reflects here
Any update on the hotel ==> reflects here
Any update on the meetin...
so what?



                               r at e!
                           nteg
                   se   ,i
            ...
so what? that was just keeping an URI.
so what? that was just keeping an URI.




       Remove ==> Cancels the flight
       Remove ==> Cancels the reservation
...
so what? that was just keeping an URI.



                                         ro l!
                                 ...
integration over the web




INTEGRATION is DECENTRALIZING the CONTROL
          delegating to multiple agents
           ...
does our ‘rest’
sites in 2010 work
      this way?
so what? that was just keeping an URI.




       Remove ==> Cancels the flight
       Remove ==> Cancels the reservation
...
so what? that was just keeping an URI.




                                    a t?
                               fo rm
 ...
mas qual o formato do
pagamento ou calendário?
#json, #xml,
#soap #etc?
qual #json, #xml
      #etc?
exercise
who is that guy?
quem é essa?
fácil? e ela?
fácil? e ela?




                          lha!
                        fi
                in ha
          é m
   n ão
conteúdo sem semântica
    não tem valor!
so what?
so what?




micro formats, media types, rdf etc
so what?



                                    nk s!
                               er li
                         hyp
  ...
integration over the web
#json,
@sergio_caelum
#?
de onde veio o # e o @?
“watching @guilhermecaelum
  #qconsp *10 great talk”


              Atenção: esse tweet é só
                  uma sugest...
controlled
vocabulary
emergiu no twitter,
  por exemplo
inventar antes o
controlled vocabulary?
top down? Big Design Up Front




   O monstro do lago SOAP, longa de 2001
economizando

# busca um voo
def voos_de(site)
  base = Restfulie.at(site).get
  voos = base.link("opensearch").get.fill("...
banco


voo = voo_mais_barato(voos)

banco = Restfulie.at("meubanco").auth(eu).get

auth = banco.cartoes["lisa"]
         ...
email
email

guilherme           super viagem
email

guilherme           super viagem
email

guilherme           super viagem



                      caelum
email

guilherme           super viagem



                      caelum
email

guilherme           super viagem



                      caelum



                       kayak
email

guilherme           super viagem



                      caelum



                       kayak
email

guilherme           super viagem



                      caelum



                       kayak
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 Ser...
Server Maturity
                1 uri, 1 http verb


public class InstallService {

  public Response execute() {
    retu...
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 {

   @G...
but...
GET hell


GET should not imply in
  undesireable effects
POST hell


GET could help us with
        cache!
Server Maturity
  Multiple uris, multiple verbs




         POST /cloud
 GET /cloud/1547437/software
POST /cloud/1547437/...
rails + restfulie
  rubyonrails.org
rails + restfulie
                   rubyonrails.org
class SoftwaresController < ApplicationController
  
  acts_as_restfu...
Vraptor
vraptor.org/en
Vraptor
                     vraptor.org/en
@Resource
public class SoftwareResource {

  public void install() {
    Softw...
JAX-RS

@Path("/softwares")
public class SoftwareResource {

  @POST @Consumes("application/xml")
  public Response instal...
JAX-RS


  @DELETE @Path("{id}")
  public Response uninstall(@PathParam("id") Long id) {
    Software software = SoftwareR...
Uniform Interface++
   Resources++
Http verbs example
POST creates

PUT replaces

PATCH updates

DELETE removes

GET retrieves

OPTIONS tells me what i can d...
Is a Restful service
   a cute CRUD?
yes
but there is more!
hypermedia
  enter amazon.com
hypermedia
  enter amazon.com

    search (GET)
hypermedia
    enter amazon.com

      search (GET)




 create a payment (POST)
hypermedia
    enter amazon.com

      search (GET)

      search (GET)



 create a payment (POST)
hypermedia
    enter amazon.com

      search (GET)

      search (GET)

  create a basket (POST)

 create a payment (POST)
hypermedia
    enter amazon.com       follow links


      search (GET)

      search (GET)

  create a basket (POST)

 cr...
hypermedia
    enter amazon.com       follow links


      search (GET)

      search (GET)
                            fil...
Cloud API

GET /user/15    retrieves an user
Cloud API

   GET /user/15         retrieves an user


follow GET machines   accesses its machines
Cloud API

   GET /user/15          retrieves an user


follow GET machines   accesses its machines


  follow POST self  ...
Cloud API

   GET /user/15          retrieves an user


follow GET machines   accesses its machines


  follow POST self  ...
retrieves an user


$ curl http://localhost:9998/user/574 -i
HTTP/1.1 200 OK
...
user

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<user>
    <link rel="machines" href="/user/574/machines"/>
...
user

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<user>
    <link rel="machines" href="/user/574/machines"/>
...
maschine maschine maschine



$ curl http://localhost:9998/user/574/machines -i
HTTP/1.1 200 OK
Content-Type: application/...
maschine
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<machines xmlns:ns2="http://www.w3.org/2005/Atom">
  <mac...
maschine
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<machines xmlns:ns2="http://www.w3.org/2005/Atom">
  <mac...
payment


<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<user>
    <link rel="machines" href="/user/574/machines...
payment


<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<user>
    <link rel="machines" href="/user/574/machines...
#buthow?
@XmlRootElement
@XmlType(propOrder= {"id", "host", "softwares", "links"})
public class Machine {
  private final all varia...
@XmlRootElement
@XmlType(propOrder= {"id", "host", "softwares", "links"})
public class Machine {
  private final all varia...
@Path("/machines")
public class MachineResource {        MachineResource
  @Path("{id}/softwares")
  public SoftwareResour...
@Path("/machines")
public class MachineResource {        MachineResource
  @Path("{id}/softwares")
  public SoftwareResour...
Server Model
according to
Leonard Richardson, 2008




                           one uri + one verb
Server Model
according to
Leonard Richardson, 2008




                               Ugly
                           one ...
Server Model
according to
Leonard Richardson, 2008




                           multiple
                            uri...
Server Model
according to
Leonard Richardson, 2008



                                      Less ugly
                    ...
Server Model
according to
Leonard Richardson, 2008


                                       multiple
                     ...
Server Model
according to
Leonard Richardson, 2008
                           cute CRUD
                                  ...
Server Model                      rest
according to
Leonard Richardson, 2008        hypermedia


                         ...
JAX-RS wishlist

  VRaptor and Restfulie
examples
vraptor.org/en
1. conventions?


@Path("/services")
public class Services {

  @GET
  public Response services(
    @QueryParam("action")...
Convention over Configuration


@Resource
public class Services {
	
	 private final ServiceFactory factory;
	
	 public Serv...
do you want to avoid
    copy+paste?
yes!
yes!
2. TDD: hard to test
@Path("/products")
public class Products {
                                   coupled to the
  @GET  ...
TDD: mock it
                                 coupled to the interface
                                        couple--

@...
TDD: mock it
                                 coupled to the interface
                                        couple--

@...
3. Content negotiation by hand

@Path("/softwares")
public class SoftwareResource {

  @POST @Consumes("application/xml")
...
Let us do it for you.


@Resource
public class SoftwareResource {

  @Post @Consumes
  public void install(Software softwa...
Let us do it for you.


@Resource
public class SoftwareResource {

  @Post @Consumes
  public void install(Software softwa...
4. URI coupling

                                   writing the URI once


...

  @GET @Path("/softwares/{id}")
  public R...
4. URI coupling
                                  writing the URI again
                                       several tim...
4. URI coupling
                                            code
@Path("/softwares")
public class SoftwareResource {

  @P...
ZERO uri replication


@Resource
public class SoftwareResource {

  @Post @Consumes
  public void install(Software softwar...
ZERO uri replication


@Resource
public class SoftwareResource {

  @Post @Consumes
  public void install(Software softwar...
5. Parameter list


@Path("/machines")
public class MachineResource {

  @Path("{id}/softwares")
  public SoftwareResource...
Yes, we can do it.


@Resource
public class MachineResource {

  @Post ("{m.id}/softwares")
  public SoftwareResource soft...
Yes, we can do it.


@Resource
public class MachineResource {

  @Post ("{m.id}/softwares")
  public SoftwareResource soft...
example
restfulie.caelumobjects.com
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.ou...
User user = response.getResource();
System.out.println("user: " + user.getName());

Link link = resource(user).getLink("ma...
Link link = resource(user).getLink("machine");
response = link.follow().post(new Machine());


double amount = resource(us...
double amount = resource(user).refresh().
                                        getAmountDue();


link = resource(user)....
link = resource(user).getLink("payment");
Payment payment = new Payment(amount);
response = link.follow().post(payment);

...
link = resource(user).getLink("payment");
Payment payment = new Payment(amount);
response = link.follow().post(payment);

...
bottom up
   design by committe
       mime type?
     microformato
  controlled vocabulary
hypermídia
viabilizando a integração através da web
obrigado
code samples


Lucas Cavalcanti
(java server)
@lucascs


           Anderson Leite (ruby)
               @anderson_leite
Further reading
Further reading
Roy Fielding dissertation
Further reading
Roy Fielding dissertation

Rest in Practice, Jim Webber and others
Further reading
Roy Fielding dissertation

Rest in Practice, Jim Webber and others

Restful Webservices Cookbook, Subbu Al...
Further reading
Roy Fielding dissertation

Rest in Practice, Jim Webber and others

Restful Webservices Cookbook, Subbu Al...
Further reading
Roy Fielding dissertation

Rest in Practice, Jim Webber and others

Restful Webservices Cookbook, Subbu Al...
Further reading
Roy Fielding dissertation

Rest in Practice, Jim Webber and others

Restful Webservices Cookbook, Subbu Al...
Further reading
Roy Fielding dissertation

Rest in Practice, Jim Webber and others

Restful Webservices Cookbook, Subbu Al...
Interviews and
 Presentations
Interviews and
             Presentations
Stefan Tilkov interview on InfoQ
Interviews and
             Presentations
Stefan Tilkov interview on InfoQ

  http://bit.ly/9RUXKL
Interviews and
             Presentations
Stefan Tilkov interview on InfoQ

  http://bit.ly/9RUXKL

Leonard Richardson’s p...
Interviews and
             Presentations
Stefan Tilkov interview on InfoQ

  http://bit.ly/9RUXKL

Leonard Richardson’s p...
Interviews and
             Presentations
Stefan Tilkov interview on InfoQ

  http://bit.ly/9RUXKL

Leonard Richardson’s p...
Interviews and
              Presentations
Stefan Tilkov interview on InfoQ

  http://bit.ly/9RUXKL

Leonard Richardson’s ...
Interviews and
 Presentations
Interviews and
             Presentations
Ian Robinson and Jim Webber interview
Interviews and
             Presentations
Ian Robinson and Jim Webber interview

 http://bit.ly/aEuzj3
Interviews and
             Presentations
Ian Robinson and Jim Webber interview

 http://bit.ly/aEuzj3

Jan Algermissen cl...
Interviews and
             Presentations
Ian Robinson and Jim Webber interview

 http://bit.ly/aEuzj3

Jan Algermissen cl...
Interviews and
              Presentations
Ian Robinson and Jim Webber interview

  http://bit.ly/aEuzj3

Jan Algermissen ...
Interviews and
              Presentations
Ian Robinson and Jim Webber interview

  http://bit.ly/aEuzj3

Jan Algermissen ...
code samples
code samples
JAX-RS
code samples
JAX-RS

 http://jcp.org/en/jsr/detail?id=311
code samples
JAX-RS

  http://jcp.org/en/jsr/detail?id=311

Rails
code samples
JAX-RS

  http://jcp.org/en/jsr/detail?id=311

Rails

  http://rubyonrails.org
code samples
JAX-RS

  http://jcp.org/en/jsr/detail?id=311

Rails

  http://rubyonrails.org

Restfulie
code samples
JAX-RS

  http://jcp.org/en/jsr/detail?id=311

Rails

  http://rubyonrails.org

Restfulie

  http://restfulie...
code samples
JAX-RS

  http://jcp.org/en/jsr/detail?id=311

Rails

  http://rubyonrails.org

Restfulie

  http://restfulie...
code samples
JAX-RS

  http://jcp.org/en/jsr/detail?id=311

Rails

  http://rubyonrails.org

Restfulie

  http://restfulie...
Arquitetura: chega de mesmice
Arquitetura: chega de mesmice
Arquitetura: chega de mesmice
Arquitetura: chega de mesmice
Arquitetura: chega de mesmice
Upcoming SlideShare
Loading in...5
×

Arquitetura: chega de mesmice

894

Published on

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

  • Be the first to like this

No Downloads
Views
Total Views
894
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
16
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide













































































  • 1 uri. 1 http verb
  • implementing a specific response






























































































  • Arquitetura: chega de mesmice

    1. 1. Arquitetura: chega de mesmice Guilherme Silveira
    2. 2. Guilherme Silveira guilherme.silveira@caelum.com.br
    3. 3. são paulo
    4. 4. são paulo
    5. 5. são paulo
    6. 6. são paulo
    7. 7. são paulo
    8. 8. Guilherme Silveira guilherme.silveira@caelum.com.br 2002 guj.com.br 2003 vraptor 2004 caelum.com.br xp, xstream 2006 scrum 2009 restfulie, lean 2010 tectura.com.br
    9. 9. bank.com calendar.com travel.com company.com
    10. 10. CORBA heaven?
    11. 11. EJB heaven?
    12. 12. SOAP heaven?
    13. 13. what is REST?
    14. 14. what is the future of integration over the web?
    15. 15. what was REST?
    16. 16. Restful Web Services
    17. 17. Restful Web create a saas account Services
    18. 18. Restful Web create a saas account freeze account Services
    19. 19. Restful Web create a saas account freeze account Services reactivate account
    20. 20. Web Restful Services
    21. 21. Web http Restful Services
    22. 22. Web http port 80 Restful Services
    23. 23. Web http port 80 firewall heaven Restful Services
    24. 24. Web Services Restful
    25. 25. Web Services xml, json Restful
    26. 26. Web Services xml, json Restful get, post, ...
    27. 27. Restful Web Services as of 2009 But what about Hypermidia? What about consumers?
    28. 28. Restful Web Services as of 2009 But what about Hypermidia? What about consumers? There is much more!
    29. 29. unresttrips.com: flight details <?xml version="1.0" encoding="UTF-8" standalum="yes"?> <flight> <information> <from>sao paulo</from> <to>seoul</to> </information>   <value>900.00</value> </flight>
    30. 30. service locator when integrating: coupling++ unrest pay unresttrips.com guilherme
    31. 31. service locator when integrating: coupling++ unrest pay unresttrips.com guilherme
    32. 32. resttrips.com: flight details <?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>
    33. 33. resttrips.com: flight details <?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>
    34. 34. resttrips.com: making the payment flight = Client.at('http://resttrips.com/f/574XR4').get(); confirmation = flight.getLink("payment"). patch(cardInformation, value);
    35. 35. resttrips.com: making the payment flight = Client.at('http://resttrips.com/f/574XR4').get(); confirmation = flight.getLink("payment"). patch(cardInformation, value);
    36. 36. resttrips.com: changing its payment provider <?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>
    37. 37. resttrips.com: changing its payment provider <?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>
    38. 38. dependency injection when integrating: coupling-- restrips pay resttrips.com guilherme paysite.com
    39. 39. dependency injection when integrating: coupling-- restrips pay resttrips.com guilherme paysite.com
    40. 40. trip = resource http://kayak.com/f/574XR4 payment = resource any_uri_unknown_at_compile_time
    41. 41. não viajo sozinho
    42. 42. meu amigo @sergio_caelum
    43. 43. meu amigo @sergio_caelum Bilu bilu
    44. 44. resttrips.com: sharing a trip flight = 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 web flight = Client.at('http://resttrips.com/f/574XR4').get(); confirmation = flight.getLink("payment"). patch(cardInformation, value/2);
    45. 45. resttrips.com: sharing a trip flight = 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 web flight = Client.at('http://resttrips.com/f/574XR4').get(); confirmation = flight.getLink("payment"). patch(cardInformation, value/2);
    46. 46. resttrips.com: sharing a trip flight = 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 web flight = Client.at('http://resttrips.com/f/574XR4').get(); confirmation = flight.getLink("payment"). patch(cardInformation, value/2);
    47. 47. resttrips.com: sharing a trip flight = 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 web flight = Client.at('http://resttrips.com/f/574XR4').get(); confirmation = flight.getLink("payment"). patch(cardInformation, value/2);
    48. 48. calendar: integrating my systems myself = Client.at('http://users.calendar.com') .with(auth).get(); myself.link("calendar").patch(flight.link("self"));
    49. 49. calendar: integrating my systems myself = Client.at('http://users.calendar.com') .with(auth).get(); myself.link("calendar").patch(flight.link("self"));
    50. 50. calendar: more examples me.link("calendar").patch(link_to_birthday_list) me.link("calendar").patch(link_to_hotel_reservation) me.link("calendar").patch(link_to_trip_details)
    51. 51. so what?
    52. 52. so what? Any update on the flight ==> reflects here Any update on the hotel ==> reflects here Any update on the meeting ==> reflects here
    53. 53. so what? r at e! nteg se ,i t u ’t j us do n Any update on the flight ==> reflects here Any update on the hotel ==> reflects here Any update on the meeting ==> reflects here
    54. 54. so what? that was just keeping an URI.
    55. 55. so what? that was just keeping an URI. Remove ==> Cancels the flight Remove ==> Cancels the reservation Remove ==> Emails your coworkers
    56. 56. so what? that was just keeping an URI. ro l! co nt a li ze en tr no tc do Remove ==> Cancels the flight Remove ==> Cancels the reservation Remove ==> Emails your coworkers
    57. 57. integration over the web INTEGRATION is DECENTRALIZING the CONTROL delegating to multiple agents distributed systems
    58. 58. does our ‘rest’ sites in 2010 work this way?
    59. 59. so what? that was just keeping an URI. Remove ==> Cancels the flight Remove ==> Cancels the reservation Remove ==> Emails your coworkers
    60. 60. so what? that was just keeping an URI. a t? fo rm hi ch bu tw Remove ==> Cancels the flight Remove ==> Cancels the reservation Remove ==> Emails your coworkers
    61. 61. mas qual o formato do pagamento ou calendário?
    62. 62. #json, #xml, #soap #etc?
    63. 63. qual #json, #xml #etc?
    64. 64. exercise
    65. 65. who is that guy?
    66. 66. quem é essa?
    67. 67. fácil? e ela?
    68. 68. fácil? e ela? lha! fi in ha é m n ão
    69. 69. conteúdo sem semântica não tem valor!
    70. 70. so what?
    71. 71. so what? micro formats, media types, rdf etc
    72. 72. so what? nk s! er li hyp w ith a ts fo rm icro m micro formats, media types, rdf etc
    73. 73. integration over the web
    74. 74. #json, @sergio_caelum
    75. 75. #?
    76. 76. de onde veio o # e o @?
    77. 77. “watching @guilhermecaelum #qconsp *10 great talk” Atenção: esse tweet é só uma sugestão!
    78. 78. controlled vocabulary
    79. 79. emergiu no twitter, por exemplo
    80. 80. inventar antes o controlled vocabulary?
    81. 81. top down? Big Design Up Front O monstro do lago SOAP, longa de 2001
    82. 82. economizando # busca um voo def voos_de(site)   base = Restfulie.at(site).get   voos = base.link("opensearch").get.fill("flight").with(:from => "GRU", :to => "JFK").get end voos = voos_de("kayak") voos << voos_de("tam") voos << voos_de("gol") voos << voos_de("cvc") voo_mais_barato(voos).link("payment").post(inferno_do_cartao)
    83. 83. banco voo = voo_mais_barato(voos) banco = Restfulie.at("meubanco").auth(eu).get auth = banco.cartoes["lisa"] .authorization(1.min, voo.preco) voo.link("payment").post(auth) mais_barato(voos).link("payment")...
    84. 84. email
    85. 85. email guilherme super viagem
    86. 86. email guilherme super viagem
    87. 87. email guilherme super viagem caelum
    88. 88. email guilherme super viagem caelum
    89. 89. email guilherme super viagem caelum kayak
    90. 90. email guilherme super viagem caelum kayak
    91. 91. email guilherme super viagem caelum kayak
    92. 92. Put your server to REST leonard richardsons model
    93. 93. Server Maturity 1 uri, 1 http verb /services.do?action=install&...
    94. 94. 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();   } }
    95. 95. Server Maturity 1 uri, 1 http verb public class InstallService {   public Response execute() {     return Response.ok()              .type("application/xml")              .entity("<service>...</service>")              .build();   } }
    96. 96. But?
    97. 97. 1 uri, 1 http verb /services.do?action=install&... I know them all beforehand.
    98. 98. 1 uri, 1 http verb /services.do?action=install&... Any change will break all our clients!
    99. 99. a priori knowledge
    100. 100. a priori knowledge =
    101. 101. a priori knowledge = coupling++
    102. 102. Server Maturity Multiple uris, 1 http verb /install?...
    103. 103. 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();   }
    104. 104. but...
    105. 105. GET hell GET should not imply in undesireable effects
    106. 106. POST hell GET could help us with cache!
    107. 107. Server Maturity Multiple uris, multiple verbs POST /cloud GET /cloud/1547437/software POST /cloud/1547437/software
    108. 108. rails + restfulie rubyonrails.org
    109. 109. rails + restfulie rubyonrails.org class 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   end end
    110. 110. Vraptor vraptor.org/en
    111. 111. Vraptor vraptor.org/en @Resource public class SoftwareResource {   public void install() {     Software software = SoftwareRepository.register (software);     response.created(software);   }   public void uninstall() {     response.deleted(software);   } }
    112. 112. 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();   }
    113. 113. JAX-RS   @DELETE @Path("{id}")   public Response uninstall(@PathParam("id") Long id) {     Software software = SoftwareRepository.retrieve(id);     software.uninstall();     return Response.ok().build();   }
    114. 114. Uniform Interface++ Resources++
    115. 115. Http verbs example POST creates PUT replaces PATCH updates DELETE removes GET retrieves OPTIONS tells me what i can do ...
    116. 116. Is a Restful service a cute CRUD?
    117. 117. yes
    118. 118. but there is more!
    119. 119. hypermedia enter amazon.com
    120. 120. hypermedia enter amazon.com search (GET)
    121. 121. hypermedia enter amazon.com search (GET) create a payment (POST)
    122. 122. hypermedia enter amazon.com search (GET) search (GET) create a payment (POST)
    123. 123. hypermedia enter amazon.com search (GET) search (GET) create a basket (POST) create a payment (POST)
    124. 124. hypermedia enter amazon.com follow links search (GET) search (GET) create a basket (POST) create a payment (POST)
    125. 125. hypermedia enter amazon.com follow links search (GET) search (GET) fill forms create a basket (POST) create a payment (POST)
    126. 126. Cloud API GET /user/15 retrieves an user
    127. 127. Cloud API GET /user/15 retrieves an user follow GET machines accesses its machines
    128. 128. Cloud API GET /user/15 retrieves an user follow GET machines accesses its machines follow POST self installs a new machine
    129. 129. Cloud API GET /user/15 retrieves an user follow GET machines accesses its machines follow POST self installs a new machine follow POST payment pay for it
    130. 130. retrieves an user $ curl http://localhost:9998/user/574 -i HTTP/1.1 200 OK ...
    131. 131. user <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <user>     <link rel="machines" href="/user/574/machines"/>     <name>guilherme silveira</name>     <website>www.caelum.com.br</site>    <link rel="payment" href="/payment/custom"/>     ... </user>
    132. 132. user <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <user>     <link rel="machines" href="/user/574/machines"/>     <name>guilherme silveira</name>     <website>www.caelum.com.br</site>    <link rel="payment" href="/payment/custom"/>     ... </user>
    133. 133. maschine maschine maschine $ curl http://localhost:9998/user/574/machines -i HTTP/1.1 200 OK Content-Type: application/xml
    134. 134. maschine <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <machines xmlns:ns2="http://www.w3.org/2005/Atom">   <machine>     <ns2:link rel="self" href="/user/574/machines/1"/>     <ns2:link rel="software" href="/machines1/softwares"/>     <id>1</id>     <host>www.caelum.com.br</host>     <softwares>       <software>         <id>1234</id>         <ns2:link rel="self" href="/softwares/1234"/>       </software>     </softwares>   </machine> </machines>
    135. 135. maschine <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <machines xmlns:ns2="http://www.w3.org/2005/Atom">   <machine>     <ns2:link rel="self" href="/user/574/machines/1"/>     <ns2:link rel="software" href="/machines1/softwares"/>     <id>1</id>     <host>www.caelum.com.br</host>     <softwares>       <software>         <id>1234</id>         <ns2:link rel="self" href="/softwares/1234"/>       </software>     </softwares>   </machine> </machines>
    136. 136. payment <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <user>     <link rel="machines" href="/user/574/machines"/>     <name>guilherme silveira</name>     <website>www.caelum.com.br</site>    <link rel="payment" href="/payment/custom"/>     ... </user>
    137. 137. payment <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <user>     <link rel="machines" href="/user/574/machines"/>     <name>guilherme silveira</name>     <website>www.caelum.com.br</site>    <link rel="payment" href="/payment/custom"/>     ... </user>
    138. 138. #buthow?
    139. 139. @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
    140. 140. @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
    141. 141. @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;
    142. 142. @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;
    143. 143. Server Model according to Leonard Richardson, 2008 one uri + one verb
    144. 144. Server Model according to Leonard Richardson, 2008 Ugly one uri + one verb
    145. 145. Server Model according to Leonard Richardson, 2008 multiple uris one uri + one verb
    146. 146. Server Model according to Leonard Richardson, 2008 Less ugly multiple uris one uri + one verb
    147. 147. Server Model according to Leonard Richardson, 2008 multiple verbs multiple uris one uri + one verb
    148. 148. Server Model according to Leonard Richardson, 2008 cute CRUD multiple verbs multiple uris one uri + one verb
    149. 149. Server Model rest according to Leonard Richardson, 2008 hypermedia multiple verbs multiple uris one uri + one verb
    150. 150. JAX-RS wishlist VRaptor and Restfulie
    151. 151. examples vraptor.org/en
    152. 152. 1. conventions? @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();   } }
    153. 153. Convention over Configuration @Resource public class Services { private final ServiceFactory factory; public Services(ServiceFactory factory) { this.factory = factory; } public void services(String action) { factory.getServiceFor(action).execute(); } }
    154. 154. do you want to avoid copy+paste?
    155. 155. yes!
    156. 156. yes!
    157. 157. 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();   } }
    158. 158. TDD: mock it coupled to the interface couple-- @Resource public class Services { private final Response response; public Services(Response response) { this.response = response; } public void services(String action) { response.getServiceFor(action).execute(); } }
    159. 159. TDD: mock it coupled to the interface couple-- @Resource public class Services { private final Response response; public Services(Response response) { this.response = response; } public void services(String action) { response.getServiceFor(action).execute(); } }
    160. 160. 3. Content negotiation by hand @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();   }
    161. 161. Let us do it for you. @Resource public class SoftwareResource { @Post @Consumes   public void install(Software software) {     software = SoftwareRepository.register(software);     response.created(software);   } }
    162. 162. Let us do it for you. @Resource public class SoftwareResource { @Post @Consumes   public void install(Software software) {     software = SoftwareRepository.register(software);     response.created(software);   } }
    163. 163. 4. URI coupling writing the URI once ...   @GET @Path("/softwares/{id}")   public Response install(@QueryParam("id") Software software) { // ...   }
    164. 164. 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();   }
    165. 165. 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();   }
    166. 166. ZERO uri replication @Resource public class SoftwareResource { @Post @Consumes   public void install(Software software) {     // ...     response.use(SoftwareResource.class).show(software);   } }
    167. 167. ZERO uri replication @Resource public class SoftwareResource { @Post @Consumes   public void install(Software software) {     // ...     response.use(SoftwareResource.class).show(software);   } }
    168. 168. 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); } // ... } }
    169. 169. Yes, we can do it. @Resource public class MachineResource { @Post ("{m.id}/softwares") public SoftwareResource softwares(Machine m) { Machine machine = new MachineRepository().retrieve(m // ... } } parameter converter chain of responsability
    170. 170. Yes, we can do it. @Resource public class MachineResource { @Post ("{m.id}/softwares") public SoftwareResource softwares(Machine m) { Machine machine = new MachineRepository().retrieve(m // ... } } parameter converter chain of responsability
    171. 171. example restfulie.caelumobjects.com
    172. 172. Response response = client.at ("http://localhost:9998/user/574").get(); 6. Client internal DSLs
    173. 173. Response response = client.at ("http://localhost:9998/user/574").get(); User user = response.getResource(); System.out.println("user: " + user.getName()); 6. Client internal DSLs
    174. 174. User user = response.getResource(); System.out.println("user: " + user.getName()); Link link = resource(user).getLink("machine"); response = link.follow().post(new Machine());
    175. 175. Link link = resource(user).getLink("machine"); response = link.follow().post(new Machine()); double amount = resource(user).refresh(). getAmountDue();
    176. 176. double amount = resource(user).refresh(). getAmountDue(); link = resource(user).getLink("payment"); Payment payment = new Payment(amount); response = link.follow().post(payment);
    177. 177. link = resource(user).getLink("payment"); Payment payment = new Payment(amount); response = link.follow().post(payment); System.out.println("payment completed");
    178. 178. link = resource(user).getLink("payment"); Payment payment = new Payment(amount); response = link.follow().post(payment); System.out.println("payment completed"); i was looking for a DSL and i did not know it!
    179. 179. bottom up design by committe mime type? microformato controlled vocabulary
    180. 180. hypermídia viabilizando a integração através da web
    181. 181. obrigado
    182. 182. code samples Lucas Cavalcanti (java server) @lucascs Anderson Leite (ruby) @anderson_leite
    183. 183. Further reading
    184. 184. Further reading Roy Fielding dissertation
    185. 185. Further reading Roy Fielding dissertation Rest in Practice, Jim Webber and others
    186. 186. Further reading Roy Fielding dissertation Rest in Practice, Jim Webber and others Restful Webservices Cookbook, Subbu Allamaraju
    187. 187. Further reading Roy Fielding dissertation Rest in Practice, Jim Webber and others Restful Webservices Cookbook, Subbu Allamaraju Restful Web Services, Richardson and Ruby
    188. 188. Further reading Roy Fielding dissertation Rest in Practice, Jim Webber and others Restful Webservices Cookbook, Subbu Allamaraju Restful Web Services, Richardson and Ruby JAX-RS specification
    189. 189. Further reading Roy Fielding dissertation Rest in Practice, Jim Webber and others Restful Webservices Cookbook, Subbu Allamaraju Restful Web Services, Richardson and Ruby JAX-RS specification Infoq articles on REST
    190. 190. Further reading Roy Fielding dissertation Rest in Practice, Jim Webber and others Restful Webservices Cookbook, Subbu Allamaraju Restful Web Services, Richardson and Ruby JAX-RS specification Infoq articles on REST Restfulie guide
    191. 191. Interviews and Presentations
    192. 192. Interviews and Presentations Stefan Tilkov interview on InfoQ
    193. 193. Interviews and Presentations Stefan Tilkov interview on InfoQ http://bit.ly/9RUXKL
    194. 194. Interviews and Presentations Stefan Tilkov interview on InfoQ http://bit.ly/9RUXKL Leonard Richardson’s presentation at QCon
    195. 195. Interviews and Presentations Stefan Tilkov interview on InfoQ http://bit.ly/9RUXKL Leonard Richardson’s presentation at QCon http://bit.ly/dj2W66
    196. 196. Interviews and Presentations Stefan Tilkov interview on InfoQ http://bit.ly/9RUXKL Leonard Richardson’s presentation at QCon http://bit.ly/dj2W66 Martin Fowler on REST
    197. 197. Interviews and Presentations Stefan Tilkov interview on InfoQ http://bit.ly/9RUXKL Leonard Richardson’s presentation at QCon http://bit.ly/dj2W66 Martin Fowler on REST http://bit.ly/bx61ci
    198. 198. Interviews and Presentations
    199. 199. Interviews and Presentations Ian Robinson and Jim Webber interview
    200. 200. Interviews and Presentations Ian Robinson and Jim Webber interview http://bit.ly/aEuzj3
    201. 201. Interviews and Presentations Ian Robinson and Jim Webber interview http://bit.ly/aEuzj3 Jan Algermissen classification
    202. 202. Interviews and Presentations Ian Robinson and Jim Webber interview http://bit.ly/aEuzj3 Jan Algermissen classification http://bit.ly/cycFBF
    203. 203. Interviews and Presentations Ian Robinson and Jim Webber interview http://bit.ly/aEuzj3 Jan Algermissen classification http://bit.ly/cycFBF Guilherme Silveira on REST clients
    204. 204. Interviews and Presentations Ian Robinson and Jim Webber interview http://bit.ly/aEuzj3 Jan Algermissen classification http://bit.ly/cycFBF Guilherme Silveira on REST clients http://bit.ly/aHCglv
    205. 205. code samples
    206. 206. code samples JAX-RS
    207. 207. code samples JAX-RS http://jcp.org/en/jsr/detail?id=311
    208. 208. code samples JAX-RS http://jcp.org/en/jsr/detail?id=311 Rails
    209. 209. code samples JAX-RS http://jcp.org/en/jsr/detail?id=311 Rails http://rubyonrails.org
    210. 210. code samples JAX-RS http://jcp.org/en/jsr/detail?id=311 Rails http://rubyonrails.org Restfulie
    211. 211. code samples JAX-RS http://jcp.org/en/jsr/detail?id=311 Rails http://rubyonrails.org Restfulie http://restfulie.caelumobjects.com
    212. 212. code samples JAX-RS http://jcp.org/en/jsr/detail?id=311 Rails http://rubyonrails.org Restfulie http://restfulie.caelumobjects.com VRaptor
    213. 213. code samples JAX-RS http://jcp.org/en/jsr/detail?id=311 Rails http://rubyonrails.org Restfulie http://restfulie.caelumobjects.com VRaptor http://vraptor.org/en
    1. A particular slide catching your eye?

      Clipping is a handy way to collect important slides you want to go back to later.

    ×