No REST for the Wicked
An overview of REST and Catalyst
By Jay Shirley <jshirley@coldhardcode.com>




                   ...
REST in 5 Minutes



          No Dragons Here




                            2
What Is REST?

Using more of HTTP 1.1




                         3
What Is REST?

Using more of HTTP 1.1
A set of ideas
  Most are good
  Most are easy




                         3
What Isn’t REST

A defined protocol




                    4
What Isn’t REST

A defined protocol
A tool for every job




                       4
What Isn’t REST

A defined protocol
A tool for every job
Good for browsers
  Since IE7, most browsers work with XmlHttpRequ...
HTTP does a lot
Common “verbs” for CRUD:
  Create an object (POST)
  Retrieve an object (GET)
  Update an object (PUT)
  D...
HTTP is Extensible

HTTP Headers:
   Content-type
   X-Your-Header
     X-AuthToken
     X-REST-Tunnel-Method (for dumb br...
What about pretty URIs?

Pretty URI ≠ REST




                          7
What about pretty URIs?

Pretty URI ≠ REST
Functional URI = REST
  /item/B9B6F0F8-1DE5-11DD-9305-CB9FBFD82403
  (still RES...
So, REST is

Using as much of the HTTP spec as you can
With URIs that...




                                            8
So, REST is

Using as much of the HTTP spec as you can
With URIs that...
  Mean something (Represent a resource or object)...
So, REST is

Using as much of the HTTP spec as you can
With URIs that...
  Mean something (Represent a resource or object)...
So, REST is

Using as much of the HTTP spec as you can
With URIs that...
  Mean something (Represent a resource or object)...
Oh, and...



        Stateless


                    9
Stateless?	

 Client holds the state
 Transactions get tricky
 Implicit trust of the client
 Trouble for web applications
...
Using REST


All or nothing? No, a la carte.
Not a standard; just good ideas
Use only what you need




                  ...
REST in more minutes...




                          12
REST is in the Request

Typical browser request:
  Host:   iwatchsoccer.com
  User-Agent: Mozilla/5.0 (Macintosh; U; Intel...
The response should
respect the request.




                       14
The response should
respect the request.
  “Accept” determines what serialization format
  (and “Content-Type”)




      ...
The response should
respect the request.
  “Accept” determines what serialization format
  (and “Content-Type”)
  “Accept-...
The response should
respect the request.
  “Accept” determines what serialization format
  (and “Content-Type”)
  “Accept-...
The response should
respect the request.
  “Accept” determines what serialization format
  (and “Content-Type”)
  “Accept-...
And now for Catalyst




                       15
Catalyst::Action::REST
 Available from CPAN
 Handles:
   Accept (Response Format)
   Request (GET, PUT, POST, DELETE)
 Eas...
And to help out...




                     17
And to help out...
 Catalyst::Controller::REST::DBIC::Item
     • I couldn’t think of a longer name
     • Just a base cla...
A Use Case

         http://www.iwatchsoccer.com/


  A simple site to list upcoming soccer matches.
      Uses Catalyst, ...
Very small

                       Team   League


 Four Basic Objects:


                       Game   Game




         ...
And some links

A game has many broadcasts
Networks have many broadcasts
A game belongs to a league
A team has many league...
Using REST


Still works in a web browser
Serializes response through Template Toolkit
Handles GET only (but doesn’t have ...
Handling other verbs

    POST, PUT, DELETE via simple commands:




                                             22
Handling other verbs

      POST, PUT, DELETE via simple commands:


$ POST -c ‘text/x-yaml’ http://localhost:3000/team


...
Handling other verbs

      POST, PUT, DELETE via simple commands:


$ POST -c ‘text/x-yaml’ http://localhost:3000/team
Pl...
Perl:


 my $lwp = LWP::UserAgent->new;
 $lwp->post( quot;http://localhost:3000/teamquot;,
  'Content-type' => 'text/x-yam...
Same idea for GET




                    24
Same idea for GET
$ GET -H ‘Content-type: text/x-yaml’ 
   http://localhost:3000/team




                                ...
Same idea for GET
$ GET -H ‘Content-type: text/x-yaml’ 
   http://localhost:3000/team


---
 -
   display_name: Urawa Red ...
Just change Content-type




                           25
Just change Content-type
$ GET -H ‘Content-type: text/x-json’ 
   http://localhost:3000/team




                         ...
Just change Content-type
$ GET -H ‘Content-type: text/x-json’ 
   http://localhost:3000/team


[{quot;token_namequot;:quot...
Not just YAML




                26
Not just YAML
Many serialization formats, from Catalyst::Action::REST




                                                ...
Not just YAML
Many serialization formats, from Catalyst::Action::REST
    YAML




                                       ...
Not just YAML
Many serialization formats, from Catalyst::Action::REST
    YAML
    JSON




                              ...
Not just YAML
Many serialization formats, from Catalyst::Action::REST
    YAML
    JSON
    XML::Simple




              ...
Not just YAML
Many serialization formats, from Catalyst::Action::REST
    YAML
    JSON
    XML::Simple
    Data::Serializ...
Not just YAML
Many serialization formats, from Catalyst::Action::REST
    YAML
    JSON
    XML::Simple
    Data::Serializ...
Not just YAML
Many serialization formats, from Catalyst::Action::REST
    YAML
    JSON
    XML::Simple
    Data::Serializ...
And, of course, HTML




                       27
Template Toolkit:




    “Serialization”
                      28
All through configuration:
 package MyApp::Controller::RestClass;
 ...
 __PACKAGE__->config(
     'default' => 'text/html',...
The REST Chain


Catalyst::DispatchType::Chained




                                  30
The REST Chain


Catalyst::DispatchType::Chained
  Very powerful




                                  30
The REST Chain


Catalyst::DispatchType::Chained
  Very powerful
  Not what this talk is about




                       ...
Starting the chain

 Two actions:
 sub rest_base : Chained(‘/’) PathPart(‘rest’)
     CaptureArgs(0) { }

 # Automatically...
What you really need:

 package IWS::Controller::Team;
 use strict;
 use warnings;
 use base 'Catalyst::Controller::REST::...
Simple Controllers
 sub rest_item_POST {

     my ( $self, $c ) = @_;

     my $data = $c->request->data;

     my $row = ...
Dispatching REST Actions
Chain is:
rest_base -> rest_item -> rest_item_${METHOD}




                                     ...
Dispatching REST Actions
Chain is:
rest_base -> rest_item -> rest_item_${METHOD}

  GET /rest/item/foo




               ...
Dispatching REST Actions
Chain is:
rest_base -> rest_item -> rest_item_${METHOD}

  GET /rest/item/foo
    calls rest_item...
Dispatching REST Actions
Chain is:
rest_base -> rest_item -> rest_item_${METHOD}

  GET /rest/item/foo
    calls rest_item...
Dispatching REST Actions
Chain is:
rest_base -> rest_item -> rest_item_${METHOD}

  GET /rest/item/foo
    calls rest_item...
Dispatching REST Actions
Chain is:
rest_base -> rest_item -> rest_item_${METHOD}

  GET /rest/item/foo
    calls rest_item...
Simple Controllers

 sub rest_item_DELETE {

     my ( $self, $c ) = @_;

     my $item = $c->stash->{rest}->{item};

    ...
More Bling

Browsers and REST do not play well...




                                        36
More Bling

Browsers and REST do not play well...
  Except inside of XmlHttpRequest




                                  ...
More Bling

Browsers and REST do not play well...
  Except inside of XmlHttpRequest
  With IE7, they all play well




   ...
More Bling

Browsers and REST do not play well...
  Except inside of XmlHttpRequest
  With IE7, they all play well
  Full ...
The Solution




http://developer.yahoo.com/yui/
                                  37
Why YUI?

Well supported
Smart hackers that know JavaScript
Smart hackers that know standards
Good documentation, code and...
YUI REST Commands


YAHOO.util.Connect.asyncRequest(
     ‘PUT’, uri, callback, data
);




                              ...
Needs a few modifications


YAHOO.util.Connect.setDefaultPostHeader(‘text/x-json’);

YAHOO.util.Connect.asyncRequest(

    ...
Still easy.




              41
Still easy.


 Set the content-type:
 YAHOO.util.Connect.setDefaultPostHeader(‘text/x-json’);




                        ...
Still easy.


 Set the content-type:
 YAHOO.util.Connect.setDefaultPostHeader(‘text/x-json’);

 Stringify the data:
 YAHOO...
Still easy.


 Set the content-type:
 YAHOO.util.Connect.setDefaultPostHeader(‘text/x-json’);

 Stringify the data:
 YAHOO...
Connecting to a form

A few points:
  Form action does not need to be what you use in
  JavaScript
  Form method does not ...
YAHOO.util.Event


var form = YAHOO.util.Dom.get(‘form_id’);

YAHOO.util.Event.on( form, ‘submit’, function() {



});



...
That’s it


 Serialize form data into JSON
 Do PUT, POST, DELETE, GET on form submit
 REST




                           ...
A word on JSON
JSON is not:
  Supposed to be eval’d
  Just JavaScript




                          45
A word on JSON
JSON is not:
  Supposed to be eval’d
  Just JavaScript
JSON is:
  Very Fast (JSON::XS and JSON::PC)
  Very ...
Upcoming SlideShare
Loading in …5
×

No REST for the Wicked: REST and Catalyst

10,803 views

Published on

Jay Shirley's talk on REST and Catalyst at YAPC::Asia

Published in: Technology
1 Comment
14 Likes
Statistics
Notes
  • The stash key is populated from the chained actions (being the object loaded), such as a URI like: /object/1 -- something up the chain has to load that object or return 404 if not found.

    Take a look at Catalyst::Controller::DBIC::API::REST -- it simplifies a lot of these chains.
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total views
10,803
On SlideShare
0
From Embeds
0
Number of Embeds
64
Actions
Shares
0
Downloads
161
Comments
1
Likes
14
Embeds 0
No embeds

No notes for slide

No REST for the Wicked: REST and Catalyst

  1. 1. No REST for the Wicked An overview of REST and Catalyst By Jay Shirley <jshirley@coldhardcode.com> 1
  2. 2. REST in 5 Minutes No Dragons Here 2
  3. 3. What Is REST? Using more of HTTP 1.1 3
  4. 4. What Is REST? Using more of HTTP 1.1 A set of ideas Most are good Most are easy 3
  5. 5. What Isn’t REST A defined protocol 4
  6. 6. What Isn’t REST A defined protocol A tool for every job 4
  7. 7. What Isn’t REST A defined protocol A tool for every job Good for browsers Since IE7, most browsers work with XmlHttpRequest Various hacks exist to DTRT 4
  8. 8. HTTP does a lot Common “verbs” for CRUD: Create an object (POST) Retrieve an object (GET) Update an object (PUT) Delete an object (DELETE) (And more, but that’s another story) 5
  9. 9. HTTP is Extensible HTTP Headers: Content-type X-Your-Header X-AuthToken X-REST-Tunnel-Method (for dumb browsers) 6
  10. 10. What about pretty URIs? Pretty URI ≠ REST 7
  11. 11. What about pretty URIs? Pretty URI ≠ REST Functional URI = REST /item/B9B6F0F8-1DE5-11DD-9305-CB9FBFD82403 (still REST) Pretty for the computer, not for you. 7
  12. 12. So, REST is Using as much of the HTTP spec as you can With URIs that... 8
  13. 13. So, REST is Using as much of the HTTP spec as you can With URIs that... Mean something (Represent a resource or object) 8
  14. 14. So, REST is Using as much of the HTTP spec as you can With URIs that... Mean something (Represent a resource or object) Don’t have to be pretty 8
  15. 15. So, REST is Using as much of the HTTP spec as you can With URIs that... Mean something (Represent a resource or object) Don’t have to be pretty Don’t have to be ugly 8
  16. 16. Oh, and... Stateless 9
  17. 17. Stateless? Client holds the state Transactions get tricky Implicit trust of the client Trouble for web applications 10
  18. 18. Using REST All or nothing? No, a la carte. Not a standard; just good ideas Use only what you need 11
  19. 19. REST in more minutes... 12
  20. 20. REST is in the Request Typical browser request: Host: iwatchsoccer.com User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9b5) Gecko/2008032619 Firefox/3.0b5 Accept: HTTP Accept=text/html,application/xhtml +xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-us,en;q=0.5 Accept-Encoding: gzip,deflate Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Keep-Alive: 300 Connection: keep-alive 13
  21. 21. The response should respect the request. 14
  22. 22. The response should respect the request. “Accept” determines what serialization format (and “Content-Type”) 14
  23. 23. The response should respect the request. “Accept” determines what serialization format (and “Content-Type”) “Accept-Language” determines what language 14
  24. 24. The response should respect the request. “Accept” determines what serialization format (and “Content-Type”) “Accept-Language” determines what language “Accept-Charset” determines what charset 14
  25. 25. The response should respect the request. “Accept” determines what serialization format (and “Content-Type”) “Accept-Language” determines what language “Accept-Charset” determines what charset Listed in order of preference from the client. 14
  26. 26. And now for Catalyst 15
  27. 27. Catalyst::Action::REST Available from CPAN Handles: Accept (Response Format) Request (GET, PUT, POST, DELETE) Easy to configure Works great 16
  28. 28. And to help out... 17
  29. 29. And to help out... Catalyst::Controller::REST::DBIC::Item • I couldn’t think of a longer name • Just a base class for yak shaving • Links DBIx::Class result sets to REST actions • Almost CRUD, except just scaffolding for it • Only a dev release on CPAN (only thing fancy about it is this slide) 17
  30. 30. A Use Case http://www.iwatchsoccer.com/ A simple site to list upcoming soccer matches. Uses Catalyst, REST and DBIx::Class 18
  31. 31. Very small Team League Four Basic Objects: Game Game 19
  32. 32. And some links A game has many broadcasts Networks have many broadcasts A game belongs to a league A team has many leagues 20
  33. 33. Using REST Still works in a web browser Serializes response through Template Toolkit Handles GET only (but doesn’t have to) 21
  34. 34. Handling other verbs POST, PUT, DELETE via simple commands: 22
  35. 35. Handling other verbs POST, PUT, DELETE via simple commands: $ POST -c ‘text/x-yaml’ http://localhost:3000/team 22
  36. 36. Handling other verbs POST, PUT, DELETE via simple commands: $ POST -c ‘text/x-yaml’ http://localhost:3000/team Please enter content (text/x-yaml) to be POSTed: --- display_name: Urawa Red Diamonds 22
  37. 37. Perl: my $lwp = LWP::UserAgent->new; $lwp->post( quot;http://localhost:3000/teamquot;, 'Content-type' => 'text/x-yaml', Content => YAML::Syck::Dump($team) ); 23
  38. 38. Same idea for GET 24
  39. 39. Same idea for GET $ GET -H ‘Content-type: text/x-yaml’ http://localhost:3000/team 24
  40. 40. Same idea for GET $ GET -H ‘Content-type: text/x-yaml’ http://localhost:3000/team --- - display_name: Urawa Red Diamonds pk1: 7 token_name: urawa-red-diamonds 24
  41. 41. Just change Content-type 25
  42. 42. Just change Content-type $ GET -H ‘Content-type: text/x-json’ http://localhost:3000/team 25
  43. 43. Just change Content-type $ GET -H ‘Content-type: text/x-json’ http://localhost:3000/team [{quot;token_namequot;:quot;urawa-red- diamondsquot;,quot;display_namequot;:quot;Urawa Red Diamondsquot;,quot;pk1quot;:7}] 25
  44. 44. Not just YAML 26
  45. 45. Not just YAML Many serialization formats, from Catalyst::Action::REST 26
  46. 46. Not just YAML Many serialization formats, from Catalyst::Action::REST YAML 26
  47. 47. Not just YAML Many serialization formats, from Catalyst::Action::REST YAML JSON 26
  48. 48. Not just YAML Many serialization formats, from Catalyst::Action::REST YAML JSON XML::Simple 26
  49. 49. Not just YAML Many serialization formats, from Catalyst::Action::REST YAML JSON XML::Simple Data::Serializer 26
  50. 50. Not just YAML Many serialization formats, from Catalyst::Action::REST YAML JSON XML::Simple Data::Serializer Any Catalyst View 26
  51. 51. Not just YAML Many serialization formats, from Catalyst::Action::REST YAML JSON XML::Simple Data::Serializer Any Catalyst View Easy to write your own 26
  52. 52. And, of course, HTML 27
  53. 53. Template Toolkit: “Serialization” 28
  54. 54. All through configuration: package MyApp::Controller::RestClass; ... __PACKAGE__->config( 'default' => 'text/html', 'map' => { 'text/html' => [ 'View', 'TT' ], 'text/xml' => [ 'View', 'TT' ] } ); 29
  55. 55. The REST Chain Catalyst::DispatchType::Chained 30
  56. 56. The REST Chain Catalyst::DispatchType::Chained Very powerful 30
  57. 57. The REST Chain Catalyst::DispatchType::Chained Very powerful Not what this talk is about 30
  58. 58. Starting the chain Two actions: sub rest_base : Chained(‘/’) PathPart(‘rest’) CaptureArgs(0) { } # Automatically defined by Catalyst::Controller::REST::DBIC::Item sub rest_item : Chained(‘rest_base’) PathPart(‘item’) CaptureArgs(1) { } 31
  59. 59. What you really need: package IWS::Controller::Team; use strict; use warnings; use base 'Catalyst::Controller::REST::DBIC::Item'; __PACKAGE__->config( # snipped general REST config 'class' => 'Schema::Team', 'item_key' => 'token_name', 'serialize_method' => 'serialize', 'browser_serialize' => 0 ); sub rest_base : Chained('/') PathPart('') CaptureArgs(0){ } 32
  60. 60. Simple Controllers sub rest_item_POST { my ( $self, $c ) = @_; my $data = $c->request->data; my $row = $self->get_rs( $c )->find_or_create($data); if ( $row ) { $self->status_created( $c, ... ); } else { $self->status_bad_request( $c, ... ); } } (but please, validate $data) 33
  61. 61. Dispatching REST Actions Chain is: rest_base -> rest_item -> rest_item_${METHOD} 34
  62. 62. Dispatching REST Actions Chain is: rest_base -> rest_item -> rest_item_${METHOD} GET /rest/item/foo 34
  63. 63. Dispatching REST Actions Chain is: rest_base -> rest_item -> rest_item_${METHOD} GET /rest/item/foo calls rest_item_GET 34
  64. 64. Dispatching REST Actions Chain is: rest_base -> rest_item -> rest_item_${METHOD} GET /rest/item/foo calls rest_item_GET PUT /rest/item/foo 34
  65. 65. Dispatching REST Actions Chain is: rest_base -> rest_item -> rest_item_${METHOD} GET /rest/item/foo calls rest_item_GET PUT /rest/item/foo calls rest_item_PUT 34
  66. 66. Dispatching REST Actions Chain is: rest_base -> rest_item -> rest_item_${METHOD} GET /rest/item/foo calls rest_item_GET PUT /rest/item/foo calls rest_item_PUT All from Catalyst::Action::REST 34
  67. 67. Simple Controllers sub rest_item_DELETE { my ( $self, $c ) = @_; my $item = $c->stash->{rest}->{item}; $item->delete; return $self->status_accepted( $c, entity => { status => ‘deleted’ } ); } 35
  68. 68. More Bling Browsers and REST do not play well... 36
  69. 69. More Bling Browsers and REST do not play well... Except inside of XmlHttpRequest 36
  70. 70. More Bling Browsers and REST do not play well... Except inside of XmlHttpRequest With IE7, they all play well 36
  71. 71. More Bling Browsers and REST do not play well... Except inside of XmlHttpRequest With IE7, they all play well Full support of POST, PUT, GET and DELETE 36
  72. 72. The Solution http://developer.yahoo.com/yui/ 37
  73. 73. Why YUI? Well supported Smart hackers that know JavaScript Smart hackers that know standards Good documentation, code and primitives 38
  74. 74. YUI REST Commands YAHOO.util.Connect.asyncRequest( ‘PUT’, uri, callback, data ); 39
  75. 75. Needs a few modifications YAHOO.util.Connect.setDefaultPostHeader(‘text/x-json’); YAHOO.util.Connect.asyncRequest( ‘PUT’, uri, callback, YAHOO.lang.JSON.stringify(data) ); 40
  76. 76. Still easy. 41
  77. 77. Still easy. Set the content-type: YAHOO.util.Connect.setDefaultPostHeader(‘text/x-json’); 41
  78. 78. Still easy. Set the content-type: YAHOO.util.Connect.setDefaultPostHeader(‘text/x-json’); Stringify the data: YAHOO.lang.JSON.stringify(data) 41
  79. 79. Still easy. Set the content-type: YAHOO.util.Connect.setDefaultPostHeader(‘text/x-json’); Stringify the data: YAHOO.lang.JSON.stringify(data) Done 41
  80. 80. Connecting to a form A few points: Form action does not need to be what you use in JavaScript Form method does not need to be what you use in JavaScript 42
  81. 81. YAHOO.util.Event var form = YAHOO.util.Dom.get(‘form_id’); YAHOO.util.Event.on( form, ‘submit’, function() { }); 43
  82. 82. That’s it Serialize form data into JSON Do PUT, POST, DELETE, GET on form submit REST 44
  83. 83. A word on JSON JSON is not: Supposed to be eval’d Just JavaScript 45
  84. 84. A word on JSON JSON is not: Supposed to be eval’d Just JavaScript JSON is: Very Fast (JSON::XS and JSON::PC) Very Small 45

×