X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=catagits%2FCatalyst-Action-REST.git;a=blobdiff_plain;f=lib%2FCatalyst%2FController%2FREST.pm;h=7ffe4131a3a16a1294a8e0d7b06999a211b9ce97;hp=e855c9ced79f0f0333c0314b487eda8ad99809d7;hb=3bb36dcaabf34fef5c15b1bb74c5eb198a7f5168;hpb=eaa7cec1399ed978f8a8083c34283ba9601edcc1 diff --git a/lib/Catalyst/Controller/REST.pm b/lib/Catalyst/Controller/REST.pm index e855c9c..7ffe413 100644 --- a/lib/Catalyst/Controller/REST.pm +++ b/lib/Catalyst/Controller/REST.pm @@ -1,8 +1,8 @@ package Catalyst::Controller::REST; -use strict; -use warnings; +use Moose; +use namespace::autoclean; -our $VERSION = '0.78'; +our $VERSION = '0.82'; $VERSION = eval $VERSION; =head1 NAME @@ -12,8 +12,10 @@ Catalyst::Controller::REST - A RESTful controller =head1 SYNOPSIS package Foo::Controller::Bar; - - use base 'Catalyst::Controller::REST'; + use Moose; + use namespace::autoclean; + + BEGIN { extends 'Catalyst::Controller::REST' } sub thing : Local : ActionClass('REST') { } @@ -34,8 +36,16 @@ Catalyst::Controller::REST - A RESTful controller # Answer PUT requests to "thing" sub thing_PUT { - .. some action .. - } + $radiohead = $req->data->{radiohead}; + + $self->status_created( + $c, + location => $c->req->uri->as_string, + entity => { + radiohead => $radiohead, + } + ); + } =head1 DESCRIPTION @@ -67,16 +77,23 @@ The serialization format will be selected based on the content-type of the incoming request. It is probably easier to use the L, which are described below. -The HTTP POST, PUT, and OPTIONS methods will all automatically deserialize the -contents of $c->request->body based on the requests content-type header. -A list of understood serialization formats is below. +"The HTTP POST, PUT, and OPTIONS methods will all automatically +L the contents of +C<< $c->request->body >> into the C<< $c->request->data >> hashref", based on +the request's C header. A list of understood serialization +formats is L. If we do not have (or cannot run) a serializer for a given content-type, a 415 "Unsupported Media Type" error is generated. To make your Controller RESTful, simply have it - use base 'Catalyst::Controller::REST'; + BEGIN { extends 'Catalyst::Controller::REST' } + +=head1 CONFIGURATION + +See L. Note that the C +key has been deprecated. =head1 SERIALIZATION @@ -85,7 +102,7 @@ responses, and deserialize any POST, PUT or OPTIONS requests. It evaluates which serializer to use by mapping a content-type to a Serialization module. We select the content-type based on: -=over 2 +=over =item B @@ -108,56 +125,60 @@ A given serialization mechanism is only available if you have the underlying modules installed. For example, you can't use XML::Simple if it's not already installed. -In addition, each serializer has it's quirks in terms of what sorts of data +In addition, each serializer has its quirks in terms of what sorts of data structures it will properly handle. L makes no attempt to save you from yourself in this regard. :) =over 2 -=item C => C +=item * C => C Returns YAML generated by L. -=item C => C +=item * C => C This uses L and L to generate YAML with all URLs turned -to hyperlinks. Only useable for Serialization. +to hyperlinks. Only usable for Serialization. -=item C => C +=item * C => C Uses L to generate JSON output. It is strongly advised to also have L installed. The C content type is supported but is deprecated and you will receive warnings in your log. -=item C => C +=item * C => C + +If a callback=? parameter is passed, this returns javascript in the form of: $callback($serializedJSON); + +=item * C => C Uses the L module to generate L output. -=item C => C +=item * C => C Uses the L module to generate L output. -=item C => C +=item * C => C Uses the L module to generate L output. -=item C => C +=item * C => C Uses the L module to generate L output. -=item C => C +=item * C => C Uses the L module to generate L output. -=item C => C +=item * C => C Uses the L module to generate L output. -=item C => C +=item * C => C Uses the L module to generate L output. -=item C => C +=item * C => C Uses L to generate XML output. This is probably not suitable for any real heavy XML work. Due to Ls requirement that the data @@ -165,37 +186,63 @@ you serialize be a HASHREF, we transform outgoing data to be in the form of: { data => $yourdata } -=item L +=item * L Uses a regular Catalyst view. For example, if you wanted to have your -C and C views rendered by TT: +C and C views rendered by TT, set: - 'text/html' => [ 'View', 'TT' ], - 'text/xml' => [ 'View', 'XML' ], + __PACKAGE__->config( + map => { + 'text/html' => [ 'View', 'TT' ], + 'text/xml' => [ 'View', 'XML' ], + } + ); -Will do the trick nicely. +Your views should have a C method like this: -=back + sub process { + my ( $self, $c, $stash_key ) = @_; + + my $output; + eval { + $output = $self->serialize( $c->stash->{$stash_key} ); + }; + return $@ if $@; -By default, L will return a C<415 Unsupported Media Type> -response if an attempt to use an unsupported content-type is made. You -can ensure that something is always returned by setting the C -config option: + $c->response->body( $output ); + return 1; # important + } + + sub serialize { + my ( $self, $data ) = @_; - __PACKAGE__->config->{'default'} = 'text/x-yaml'; + my $serialized = ... process $data here ... -Would make it always fall back to the serializer plugin defined for text/x-yaml. + return $serialized; + } -Implementing new Serialization formats is easy! Contributions -are most welcome! See L and -L for more information. +=back + +By default, L will return a +C<415 Unsupported Media Type> response if an attempt to use an unsupported +content-type is made. You can ensure that something is always returned by +setting the C config option: + + __PACKAGE__->config(default => 'text/x-yaml'); + +would make it always fall back to the serializer plugin defined for +C. =head1 CUSTOM SERIALIZERS -If you would like to implement a custom serializer, you should create two new -modules in the L and -L namespace. Then assign your new class -to the content-type's you want, and you're done. +Implementing new Serialization formats is easy! Contributions +are most welcome! If you would like to implement a custom serializer, +you should create two new modules in the L +and L namespace. Then assign your new +class to the content-type's you want, and you're done. + +See L and L +for more information. =head1 STATUS HELPERS @@ -208,11 +255,11 @@ refer to it at: L. These routines are all implemented as regular subroutines, and as such require you pass the current context ($c) as the first argument. -=over 4 +=over =cut -use base 'Catalyst::Controller'; +BEGIN { extends 'Catalyst::Controller' } use Params::Validate qw(SCALAR OBJECT); __PACKAGE__->mk_accessors(qw(serialize)); @@ -225,12 +272,15 @@ __PACKAGE__->config( 'text/x-yaml' => 'YAML', 'application/json' => 'JSON', 'text/x-json' => 'JSON', + 'application/x-javascript' => 'JSONP', + 'application/javascript' => 'JSONP', + 'text/javascript' => 'JSONP', 'text/x-data-dumper' => [ 'Data::Serializer', 'Data::Dumper' ], 'text/x-data-denter' => [ 'Data::Serializer', 'Data::Denter' ], 'text/x-data-taxi' => [ 'Data::Serializer', 'Data::Taxi' ], - 'application/x-storable' => [ 'Data::Serializer', 'Storable' ], - 'application/x-freezethaw' => [ 'Data::Serializer', 'FreezeThaw' ], - 'text/x-config-general' => [ 'Data::Serializer', 'Config::General' ], + 'application/x-storable' => [ 'Data::Serializer', 'Storable' ], + 'application/x-freezethaw' => [ 'Data::Serializer', 'FreezeThaw' ], + 'text/x-config-general' => [ 'Data::Serializer', 'Config::General' ], 'text/x-php-serialization' => [ 'Data::Serializer', 'PHP::Serialization' ], }, ); @@ -452,26 +502,24 @@ L and L. It should This class provides a default configuration for Serialization. It is currently: __PACKAGE__->config( - serialize => { - 'stash_key' => 'rest', - 'map' => { - 'text/html' => 'YAML::HTML', - 'text/xml' => 'XML::Simple', - 'text/x-yaml' => 'YAML', - 'application/json' => 'JSON', - 'text/x-json' => 'JSON', - 'text/x-data-dumper' => [ 'Data::Serializer', 'Data::Dumper' ], - 'text/x-data-denter' => [ 'Data::Serializer', 'Data::Denter' ], - 'text/x-data-taxi' => [ 'Data::Serializer', 'Data::Taxi' ], - 'application/x-storable' => [ 'Data::Serializer', 'Storable' -], - 'application/x-freezethaw' => [ 'Data::Serializer', 'FreezeThaw' -], - 'text/x-config-general' => [ 'Data::Serializer', 'Config::General' ] -, - 'text/x-php-serialization' => [ 'Data::Serializer', 'PHP::Serialization' ], - }, - } + 'stash_key' => 'rest', + 'map' => { + 'text/html' => 'YAML::HTML', + 'text/xml' => 'XML::Simple', + 'text/x-yaml' => 'YAML', + 'application/json' => 'JSON', + 'text/x-json' => 'JSON', + 'application/x-javascript' => 'JSONP', + 'application/javascript' => 'JSONP', + 'text/javascript' => 'JSONP', + 'text/x-data-dumper' => [ 'Data::Serializer', 'Data::Dumper' ], + 'text/x-data-denter' => [ 'Data::Serializer', 'Data::Denter' ], + 'text/x-data-taxi' => [ 'Data::Serializer', 'Data::Taxi' ], + 'application/x-storable' => [ 'Data::Serializer', 'Storable' ], + 'application/x-freezethaw' => [ 'Data::Serializer', 'FreezeThaw' ], + 'text/x-config-general' => [ 'Data::Serializer', 'Config::General' ], + 'text/x-php-serialization' => [ 'Data::Serializer', 'PHP::Serialization' ], + }, ); You can read the full set of options for this configuration block in @@ -484,8 +532,11 @@ method uses L. If you want to override either behavior, simply implement your own C and C actions and use MRO::Compat: - my Foo::Controller::Monkey; - use base qw(Catalyst::Controller::REST); + package Foo::Controller::Monkey; + use Moose; + use namespace::autoclean; + + BEGIN { extends 'Catalyst::Controller::REST' } sub begin :Private { my ($self, $c) = @_; @@ -507,7 +558,7 @@ and use MRO::Compat: I have code in production using L. That said, it is still under development, and it's possible that things may change -between releases. I promise to not break things unneccesarily. :) +between releases. I promise to not break things unnecessarily. :) =head1 SEE ALSO @@ -522,15 +573,9 @@ Wikipedia! http://en.wikipedia.org/wiki/Representational_State_Transfer The REST Wiki: http://rest.blueoxen.net/cgi-bin/wiki.pl?FrontPage -=head1 AUTHOR - -Adam Jacob , with lots of help from mst and jrockway - -Marchex, Inc. paid me while I developed this module. (http://www.marchex.com) - -=head1 MAINTAINER +=head1 AUTHORS -J. Shirley +See L for authors. =head1 LICENSE