Upload
jay-shirley
View
10.080
Download
3
Tags:
Embed Size (px)
DESCRIPTION
Jay Shirley's talk on REST and Catalyst at YAPC::Asia
Citation preview
No REST for the WickedAn overview of REST and CatalystBy Jay Shirley <[email protected]>
1
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 XmlHttpRequest
Various hacks exist to DTRT
4
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
HTTP is Extensible
HTTP Headers:
Content-type
X-Your-Header
X-AuthToken
X-REST-Tunnel-Method (for dumb browsers)
6
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 REST)
Pretty for the computer, not for you.
7
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)
8
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
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
Oh, and...
Stateless
9
Stateless?
Client holds the state
Transactions get tricky
Implicit trust of the client
Trouble for web applications
10
Using REST
All or nothing? No, a la carte.
Not a standard; just good ideas
Use only what you need
11
REST in more minutes...
12
REST is in the Request
Typical browser request:Host: iwatchsoccer.comUser-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9b5) Gecko/2008032619 Firefox/3.0b5Accept: HTTP Accept=text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8Accept-Language: en-us,en;q=0.5Accept-Encoding: gzip,deflateAccept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7Keep-Alive: 300Connection: keep-alive
13
The response should respect the request.
14
The response should respect the request.
“Accept” determines what serialization format(and “Content-Type”)
14
The response should respect the request.
“Accept” determines what serialization format(and “Content-Type”)
“Accept-Language” determines what language
14
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
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
And now for Catalyst
15
Catalyst::Action::REST
Available from CPAN
Handles:
Accept (Response Format)
Request (GET, PUT, POST, DELETE)
Easy to configure
Works great
16
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 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
A Use Case
http://www.iwatchsoccer.com/
A simple site to list upcoming soccer matches.
Uses Catalyst, REST and DBIx::Class
18
Very small
Four Basic Objects:
Team League
Game Game
19
And some links
A game has many broadcasts
Networks have many broadcasts
A game belongs to a league
A team has many leagues
20
Using REST
Still works in a web browser
Serializes response through Template Toolkit
Handles GET only (but doesn’t have to)
21
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
22
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
Perl:
my $lwp = LWP::UserAgent->new;$lwp->post( "http://localhost:3000/team",'Content-type' => 'text/x-yaml',
Content => YAML::Syck::Dump($team));
23
Same idea for GET
24
Same idea for GET
$ GET -H ‘Content-type: text/x-yaml’ \http://localhost:3000/team
24
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
Just change Content-type
25
Just change Content-type
$ GET -H ‘Content-type: text/x-json’ \http://localhost:3000/team
25
Just change Content-type
$ GET -H ‘Content-type: text/x-json’ \http://localhost:3000/team
[{"token_name":"urawa-red-diamonds","display_name":"Urawa Red Diamonds","pk1":7}]
25
Not just YAML
26
Not just YAML
Many serialization formats, from Catalyst::Action::REST
26
Not just YAML
Many serialization formats, from Catalyst::Action::REST
YAML
26
Not just YAML
Many serialization formats, from Catalyst::Action::REST
YAML
JSON
26
Not just YAML
Many serialization formats, from Catalyst::Action::REST
YAML
JSON
XML::Simple
26
Not just YAML
Many serialization formats, from Catalyst::Action::REST
YAML
JSON
XML::Simple
Data::Serializer
26
Not just YAML
Many serialization formats, from Catalyst::Action::REST
YAML
JSON
XML::Simple
Data::Serializer
Any Catalyst View
26
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
And, of course, HTML
27
Template Toolkit:
“Serialization”
28
All through configuration:
package MyApp::Controller::RestClass;...__PACKAGE__->config( 'default' => 'text/html', 'map' => { 'text/html' => [ 'View', 'TT' ], 'text/xml' => [ 'View', 'TT' ] });
29
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
30
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
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
Simple Controllerssub 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
Dispatching REST Actions
Chain is:rest_base -> rest_item -> rest_item_${METHOD}
34
Dispatching REST Actions
Chain is:rest_base -> rest_item -> rest_item_${METHOD}
GET /rest/item/foo
34
Dispatching REST Actions
Chain is:rest_base -> rest_item -> rest_item_${METHOD}
GET /rest/item/foo
calls rest_item_GET
34
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
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
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
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
More Bling
Browsers and REST do not play well...
36
More Bling
Browsers and REST do not play well...
Except inside of XmlHttpRequest
36
More Bling
Browsers and REST do not play well...
Except inside of XmlHttpRequest
With IE7, they all play well
36
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
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 primitives
38
YUI REST Commands
YAHOO.util.Connect.asyncRequest(
‘PUT’, uri, callback, data
);
39
Needs a few modifications
YAHOO.util.Connect.setDefaultPostHeader(‘text/x-json’);
YAHOO.util.Connect.asyncRequest(
‘PUT’, uri, callback, YAHOO.lang.JSON.stringify(data)
);
40
Still easy.
41
Still easy.
Set the content-type:YAHOO.util.Connect.setDefaultPostHeader(‘text/x-json’);
41
Still easy.
Set the content-type:YAHOO.util.Connect.setDefaultPostHeader(‘text/x-json’);
Stringify the data:YAHOO.lang.JSON.stringify(data)
41
Still easy.
Set the content-type:YAHOO.util.Connect.setDefaultPostHeader(‘text/x-json’);
Stringify the data:YAHOO.lang.JSON.stringify(data)
Done
41
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
YAHOO.util.Event
var form = YAHOO.util.Dom.get(‘form_id’);
YAHOO.util.Event.on( form, ‘submit’, function() {
});
43
That’s it
Serialize form data into JSON
Do PUT, POST, DELETE, GET on form submit
REST
44
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 Small
45