[Catalyst] Beginner Question: Controller Layout

J. Shirley jshirley at gmail.com
Wed Dec 10 02:50:44 GMT 2008

On Tue, Dec 9, 2008 at 7:17 AM, David Schmidt <davewood at gmx.at> wrote:
> Hello list,
> I am at the point of starting a new project and have yet to choose a
> controller layout.
> my application is a site where:
> music bands can
> -   register
> -   fill out (and later edit) a profile
> -   upload pictures and songs
> -   schedule events which will be displayed on a calendar
> visitors can
> -   browse all of the above information
> -   register to a newsletter
> admins can
> -   edit all of the above stuff
> Well, I suppose you get the picture. I am hoping to get some guidance
> here from someone who has experience
> One solution that comes to my mind would be to make a controlller for
> each role (admin, band, visitor)
> another one would be to make a controller for each type of media
> (songs, pictures, band, ...)
> Either way I am not able to tell which one is most suitable beforehand.
> thanks in advance
> david

Hi David,

Whenever I'm building a new application I always try to think of the
URI scheme, and how I can construct it to be the most RESTful and
still the most sane (the distinction between REST and RPC is to not
have create/edit/delete URIs; this is why I say RESTful rather than
strict REST).

Then I try to associate every ownership pattern that may exist.  For
example, if a member can belong to one or more bands, then the member
is a root level action, and you would have /member/{id} (an important
note at the bottom to read, too).

Under a member account, you would have your bands.  That would create
/member/{id}/band for a listing, and then /member/{id}/band/{id} for a
specific band.

You can continue this path down the chain for any level of ownership.

Now, as it associates to controllers is quite simple but may require a
bit of experimenting to get right.  The secret sauce lies in using
base controllers to build up your individual items (band, member,
song) so that you can use the Chained dispatch type, and have
instances of the base controllers in various points of the URI chains,
with a resultset (assuming you use DBIx::Class) that is chained along
with it.

So, you can have a URI structure like:

Then, you really only have to maintain one set of controllers, as the
others should consist of little more than configuration on how to
access the DBIx::Class::ResultSet to use to find the record, and then
a simple 'use parent "MyApp::ControllerBase::Band";' (or whatever) and
you're set.

An important note on URI construction:
If you have lookups like "/member/joe_schmoe" and a RPC-based URI
structure with URIs like /thing/(create|edit|delete) then you have to
make sure that the token you use to query is never
qr/create|edit|delete/.  This is a silly restriction, and it ends up
binding you to using just numeric ids or not allowing arbitrary
tokens.  A popular scheme is instead to use /member/id/{numeric_id} or
/member/name/joe_schmoe then you have /member/(create|edit|delete)
without any possibility of conflict.

Hope this helps, and if you want more information you can tune into
the talk I'm giving at Orlando Perl Oasis next month (hopefully will
see you there) where I'm going over this exact subject!  You can see
more details at http://perloasis.org/opw2009/


More information about the Catalyst mailing list