[Catalyst] Add a /doc/ path at the end of all paths?

J. Shirley jshirley at gmail.com
Thu Feb 26 16:05:15 GMT 2009


On Thu, Feb 26, 2009 at 7:14 AM, Ovid <publiustemp-catalyst at yahoo.com>wrote:

> Hi all,
>
> We're trying to make our REST API a bit more friendly,  We have a base
> class for our REST API which inherits from Catalyst::Controller::REST.   =
Our
> various REST classes which inherit from this and each class can identify =
the
> query parameters it accepts.  So we thought it would be nice to put this
> into the base class:
>
>  sub doc : Regex('/doc$') {
>      my ($self, $c) =3D @_;
>      $c->stash->{params} =3D $c->forward('allowed_query_params');
>  }
>
> And from there, every REST url could have /doc/ added to the end to show
> which query parameters it accepts.
>
> It doesn't work.  $self is *always* a PIPs::C::API::V1::Franchise instanc=
e,
> no matter which URL is called.  This appears to be because of this:
>
>  [26 Feb 2009 15:07:40,509] [Catalyst.Dispatcher] [DEBUG] Loaded Private
> actions:
>
>  .-----------------------+--------------------------------------+--------=
------.
>  | Private               | Class                                | Method
>     |
>
>  +-----------------------+--------------------------------------+--------=
------+
>  ...
>  | /api/v1/franchise/doc | PIPs::C::Api::V1::Franchise          | doc
>    |
>
> So the very first instance of the "doc" method dispatches through
> Franchise, even if the controller for a given URL would be API::V1::Warni=
ng
> or something like that.
>
> How can I work around this?  LocalRegex doesn't work, obviously, and
> chained actions don't seem appropriate because, due to the nature of our
> app, we never know how many path parts will be between '/api/v1/' and
> '/doc/'.
>
> What am I missing? :)
>
> Cheers,
> Ovid
>

If you structure your base class properly, and then in each class you
configure where to chain from:

__PACKAGE__->config(
     actions =3D> { 'setup' =3D> { Chained =3D> '/some/other/chain', PathPa=
rt =3D>
'api' } }
);

You can override any of the methods along the way.  I tend to use this
structure in my base class:

sub setup : Chained('.') PathPart('something') CaptureArgs(0) { }

sub root : Chained('setup') PathPart('') Args(0) { }

sub object_setup : Chained('setup') PathPart('id') CaptureArgs(1) { }

sub object : Chained('object_setup') PathPart('') Args(0) { }

This way, you could add a: sub doc : Chained('setup') PathPart('doc')
Args(0) { } method and you would always have it.

I have an example app on github that demonstrates this idea more:
http://github.com/jshirley/catalystx-example-chained/tree/master

I'm currently using this same mechanism in a similar way, except instead of
a 'doc' it is a 'search' method that returns content-type aware search
results (for use as a backend data provider to a live-editing YUI datatable)

-J
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.scsys.co.uk/pipermail/catalyst/attachments/20090226/f3779=
7ce/attachment.htm


More information about the Catalyst mailing list