Bump versions for release
[catagits/Catalyst-Action-REST.git] / lib / Catalyst / Action / Serialize.pm
CommitLineData
7ad87df9 1package Catalyst::Action::Serialize;
2
930013e6 3use Moose;
4use namespace::autoclean;
7ad87df9 5
930013e6 6extends 'Catalyst::Action::SerializeBase';
7ad87df9 7use Module::Pluggable::Object;
def65dcc 8use MRO::Compat;
7ad87df9 9
3bb36dca 10our $VERSION = '0.82';
f465980c 11$VERSION = eval $VERSION;
12
0c14c8cd 13has _encoders => (
14 is => 'ro',
15 isa => 'HashRef',
16 default => sub { {} },
17);
18
7ad87df9 19sub execute {
20 my $self = shift;
21 my ( $controller, $c ) = @_;
22
def65dcc 23 $self->maybe::next::method(@_);
e601adda 24
7ad87df9 25 return 1 if $c->req->method eq 'HEAD';
26 return 1 if length( $c->response->body );
27 return 1 if scalar @{ $c->error };
28 return 1 if $c->response->status =~ /^(?:204|3\d\d)$/;
29
9a76221e 30 my ( $sclass, $sarg, $content_type ) =
31 $self->_load_content_plugins( "Catalyst::Action::Serialize",
32 $controller, $c );
51cc8fe9 33 unless ( defined($sclass) ) {
9a76221e 34 if ( defined($content_type) ) {
faf5c20b 35 $c->log->info("Could not find a serializer for $content_type");
9a76221e 36 } else {
faf5c20b 37 $c->log->info(
9cd203c9 38 "Could not find a serializer for an empty content-type");
9a76221e 39 }
51cc8fe9 40 return 1;
41 }
9a76221e 42 $c->log->debug(
faf5c20b 43 "Serializing with $sclass" . ( $sarg ? " [$sarg]" : '' ) ) if $c->debug;
7ad87df9 44
0c14c8cd 45 $self->_encoders->{$sclass} ||= $sclass->new;
46 my $sobj = $self->_encoders->{$sclass};
47
e601adda 48 my $rc;
878b2b54 49 eval {
50 if ( defined($sarg) ) {
0c14c8cd 51 $rc = $sobj->execute( $controller, $c, $sarg );
878b2b54 52 } else {
0c14c8cd 53 $rc = $sobj->execute( $controller, $c );
878b2b54 54 }
55 };
56 if ($@) {
57 return $self->_serialize_bad_request( $c, $content_type, $@ );
58 } elsif (!$rc) {
9a76221e 59 return $self->_unsupported_media_type( $c, $content_type );
9a76221e 60 }
7ad87df9 61
62 return 1;
eccb2137 63}
7ad87df9 64
05009b91 65__PACKAGE__->meta->make_immutable;
398c5a1b 66
67=head1 NAME
68
69Catalyst::Action::Serialize - Serialize Data in a Response
70
71=head1 SYNOPSIS
72
73 package Foo::Controller::Bar;
74
75 __PACKAGE__->config(
faf5c20b 76 'default' => 'text/x-yaml',
77 'stash_key' => 'rest',
78 'map' => {
79 'text/html' => [ 'View', 'TT', ],
80 'text/x-yaml' => 'YAML',
81 'text/x-data-dumper' => [ 'Data::Serializer', 'Data::Dumper' ],
398c5a1b 82 }
83 );
84
e601adda 85 sub end :ActionClass('Serialize') {}
398c5a1b 86
87=head1 DESCRIPTION
88
89This action will serialize the body of an HTTP Response. The serializer is
e601adda 90selected by introspecting the HTTP Requests content-type header.
398c5a1b 91
faf5c20b 92It requires that your Catalyst controller is properly configured to set up the
93mapping between Content Type's and Serialization classes.
398c5a1b 94
faf5c20b 95The specifics of serializing each content-type is implemented as a plugin to
96L<Catalyst::Action::Serialize>.
398c5a1b 97
e601adda 98Typically, you would use this ActionClass on your C<end> method. However,
99nothing is stopping you from choosing specific methods to Serialize:
100
101 sub foo :Local :ActionClass('Serialize') {
102 .. populate stash with data ..
103 }
104
9a76221e 105When you use this module, the request class will be changed to
106L<Catalyst::Request::REST>.
107
398c5a1b 108=head1 CONFIGURATION
109
a51e7bbd 110=head2 map
398c5a1b 111
a51e7bbd 112Takes a hashref, mapping Content-Types to a given serializer plugin.
398c5a1b 113
a51e7bbd 114=head2 default
367b3ff4 115
a51e7bbd 116This is the 'fall-back' Content-Type if none of the requested or acceptable
117types is found in the L</map>. It must be an entry in the L</map>.
398c5a1b 118
0c14c8cd 119=head2 stash_key
398c5a1b 120
a51e7bbd 121Specifies the key of the stash entry holding the data that is to be serialized.
122So if the value is "rest", we will serialize the data under:
e601adda 123
124 $c->stash->{'rest'}
398c5a1b 125
a51e7bbd 126=head2 content_type_stash_key
398c5a1b 127
a51e7bbd 128Specifies the key of the stash entry that optionally holds an overriding
129Content-Type. If set, and if the specified stash entry has a valid value,
130then it takes priority over the requested content types.
398c5a1b 131
a51e7bbd 132This can be useful if you want to dynamically force a particular content type,
133perhaps for debugging.
398c5a1b 134
e601adda 135=head1 HELPFUL PEOPLE
136
137Daisuke Maki pointed out that early versions of this Action did not play
138well with others, or generally behave in a way that was very consistent
0c14c8cd 139with the rest of Catalyst.
e601adda 140
398c5a1b 141=head1 SEE ALSO
142
143You likely want to look at L<Catalyst::Controller::REST>, which implements
e601adda 144a sensible set of defaults for doing a REST controller.
398c5a1b 145
146L<Catalyst::Action::Deserialize>, L<Catalyst::Action::REST>
147
5cb5f6bb 148=head1 AUTHORS
398c5a1b 149
5cb5f6bb 150See L<Catalyst::Action::REST> for authors.
398c5a1b 151
152=head1 LICENSE
153
154You may distribute this code under the same terms as Perl itself.
155
156=cut