Your SlideShare is downloading. ×
No REST for the Wicked: REST and Catalyst
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

No REST for the Wicked: REST and Catalyst

10,053
views

Published on

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

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,053
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
158
Comments
1
Likes
14
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. No REST for the Wicked An overview of REST and Catalyst By Jay Shirley <jshirley@coldhardcode.com> 1
  • 2. REST in 5 Minutes No Dragons Here 2
  • 3. What Is REST? Using more of HTTP 1.1 3
  • 4. What Is REST? Using more of HTTP 1.1 A set of ideas Most are good Most are easy 3
  • 5. What Isn’t REST A defined protocol 4
  • 6. What Isn’t REST A defined protocol A tool for every job 4
  • 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. 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. HTTP is Extensible HTTP Headers: Content-type X-Your-Header X-AuthToken X-REST-Tunnel-Method (for dumb browsers) 6
  • 10. What about pretty URIs? Pretty URI ≠ REST 7
  • 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. So, REST is Using as much of the HTTP spec as you can With URIs that... 8
  • 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. 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. 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. Oh, and... Stateless 9
  • 17. Stateless? Client holds the state Transactions get tricky Implicit trust of the client Trouble for web applications 10
  • 18. Using REST All or nothing? No, a la carte. Not a standard; just good ideas Use only what you need 11
  • 19. REST in more minutes... 12
  • 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. The response should respect the request. 14
  • 22. The response should respect the request. “Accept” determines what serialization format (and “Content-Type”) 14
  • 23. The response should respect the request. “Accept” determines what serialization format (and “Content-Type”) “Accept-Language” determines what language 14
  • 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. 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. And now for Catalyst 15
  • 27. Catalyst::Action::REST Available from CPAN Handles: Accept (Response Format) Request (GET, PUT, POST, DELETE) Easy to configure Works great 16
  • 28. And to help out... 17
  • 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. A Use Case http://www.iwatchsoccer.com/ A simple site to list upcoming soccer matches. Uses Catalyst, REST and DBIx::Class 18
  • 31. Very small Team League Four Basic Objects: Game Game 19
  • 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. Using REST Still works in a web browser Serializes response through Template Toolkit Handles GET only (but doesn’t have to) 21
  • 34. Handling other verbs POST, PUT, DELETE via simple commands: 22
  • 35. Handling other verbs POST, PUT, DELETE via simple commands: $ POST -c ‘text/x-yaml’ http://localhost:3000/team 22
  • 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. 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. Same idea for GET 24
  • 39. Same idea for GET $ GET -H ‘Content-type: text/x-yaml’ http://localhost:3000/team 24
  • 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. Just change Content-type 25
  • 42. Just change Content-type $ GET -H ‘Content-type: text/x-json’ http://localhost:3000/team 25
  • 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. Not just YAML 26
  • 45. Not just YAML Many serialization formats, from Catalyst::Action::REST 26
  • 46. Not just YAML Many serialization formats, from Catalyst::Action::REST YAML 26
  • 47. Not just YAML Many serialization formats, from Catalyst::Action::REST YAML JSON 26
  • 48. Not just YAML Many serialization formats, from Catalyst::Action::REST YAML JSON XML::Simple 26
  • 49. Not just YAML Many serialization formats, from Catalyst::Action::REST YAML JSON XML::Simple Data::Serializer 26
  • 50. Not just YAML Many serialization formats, from Catalyst::Action::REST YAML JSON XML::Simple Data::Serializer Any Catalyst View 26
  • 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. And, of course, HTML 27
  • 53. Template Toolkit: “Serialization” 28
  • 54. All through configuration: package MyApp::Controller::RestClass; ... __PACKAGE__->config( 'default' => 'text/html', 'map' => { 'text/html' => [ 'View', 'TT' ], 'text/xml' => [ 'View', 'TT' ] } ); 29
  • 55. The REST Chain Catalyst::DispatchType::Chained 30
  • 56. The REST Chain Catalyst::DispatchType::Chained Very powerful 30
  • 57. The REST Chain Catalyst::DispatchType::Chained Very powerful Not what this talk is about 30
  • 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. 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. 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. Dispatching REST Actions Chain is: rest_base -> rest_item -> rest_item_${METHOD} 34
  • 62. Dispatching REST Actions Chain is: rest_base -> rest_item -> rest_item_${METHOD} GET /rest/item/foo 34
  • 63. Dispatching REST Actions Chain is: rest_base -> rest_item -> rest_item_${METHOD} GET /rest/item/foo calls rest_item_GET 34
  • 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. 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. 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. 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. More Bling Browsers and REST do not play well... 36
  • 69. More Bling Browsers and REST do not play well... Except inside of XmlHttpRequest 36
  • 70. More Bling Browsers and REST do not play well... Except inside of XmlHttpRequest With IE7, they all play well 36
  • 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. The Solution http://developer.yahoo.com/yui/ 37
  • 73. Why YUI? Well supported Smart hackers that know JavaScript Smart hackers that know standards Good documentation, code and primitives 38
  • 74. YUI REST Commands YAHOO.util.Connect.asyncRequest( ‘PUT’, uri, callback, data ); 39
  • 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. Still easy. 41
  • 77. Still easy. Set the content-type: YAHOO.util.Connect.setDefaultPostHeader(‘text/x-json’); 41
  • 78. Still easy. Set the content-type: YAHOO.util.Connect.setDefaultPostHeader(‘text/x-json’); Stringify the data: YAHOO.lang.JSON.stringify(data) 41
  • 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. 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. YAHOO.util.Event var form = YAHOO.util.Dom.get(‘form_id’); YAHOO.util.Event.on( form, ‘submit’, function() { }); 43
  • 82. That’s it Serialize form data into JSON Do PUT, POST, DELETE, GET on form submit REST 44
  • 83. A word on JSON JSON is not: Supposed to be eval’d Just JavaScript 45
  • 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

×