Subject: | Documentation about overriding Catalyst::Controller::REST::begin() is either ambiguous or wrong |
The Catalyst::Controller::REST documentation suggests that it should be possible to override
the begin() and end() methods in your Catalyst::Controller::REST-extended controller without
losing access to the (de)serialization methods that are automatically supplied via
ActionClass() attributes in Catalyst::Controller::REST. Specifically, the documentation says:
The "begin" method uses Catalyst::Action::Deserialize. The "end" method uses
Catalyst::Action::Serialize. If you want to override either behavior, simply
implement your own "begin" and "end" actions and use MRO::Compat:
package Foo::Controller::Monkey;
use Moose;
use namespace::autoclean;
BEGIN { extends ’Catalyst::Controller::REST’ }
sub begin :Private {
my ($self, $c) = @_;
... do things before Deserializing ...
$self->maybe::next::method($c);
... do things after Deserializing ...
}
Either I misunderstood the documentation, or this is wrong. In the attached example
controller simple::Controller::Root, it seems that my begin() method never gets through to
the Catalyst::Controller::REST's deserialization action.
Specifically, if you run the attached test.pl against the attached controller package with the
begin() block commented out you get the expected output:
<opt>
<data hello="world" you_said="Whee" />
</opt>
However, if you uncomment the begin() block - which is *supposed* to eventually dispatch to
the deserialization action of Catalyst::Controller::REST::begin() - the output method foo_POST
fails due to the fact that $c->request->data is empty:
Caught exception in simple::Controller::Root->echo_POST "Can't use an undefined value as a
HASH reference at /tmp/simple/script/../lib/simple/Controller/Root.pm line 23."
So I'm filing this as a bug to either get the dispatching behavior fixed, or to learn what I
misunderstood (and therefore how the documentation can be fixed).
Note that the bug does go away if I simply declare
sub begin :ActionClass('Deserialize') { }
but that seemed not to be what the documentation suggested I do.
Subject: | Root.pm |
package simple::Controller::Root;
use Moose;
use namespace::autoclean;
BEGIN { extends 'Catalyst::Controller::REST' }
__PACKAGE__->config(namespace => '');
sub begin
{
my $self = shift;
my $c = shift;
$self->maybe::next::method($c);
}
sub echo: Local : ActionClass('REST')
{
}
sub echo_POST : Private
{
my ($self, $c) = @_;
$self->status_ok(
$c,
entity => {
hello => 'world',
you_said => $c->request->data->{input},
},
);
}
__PACKAGE__->meta->make_immutable;
1;
Subject: | test.pl |
#!/usr/bin/perl
use strict;
use warnings;
use LWP::UserAgent;
use XML::Simple;
my $host = 'localhost:3000';
my $args = {input => 'Whee',};
my $xml = XML::Simple::XMLout($args);
my $url = "http://$host/echo";
my $ua = LWP::UserAgent->new;
my $result = $ua->post(
$url,
'Content-type' => 'text/xml',
Content => $xml
);
print $result->content;
1;