[Catalyst] RFC: Catalyst::Controller::REST::DBIC

luke saunders luke.saunders at gmail.com
Sun May 4 14:58:52 BST 2008


On Sun, May 4, 2008 at 2:18 PM, Jonathan Rockway <jon at jrock.us> wrote:
> * On Sat, May 03 2008, luke saunders wrote:
>  >   __PACKAGE__->config
>  >     ( action => { setup => { PathPart => 'cd', Chained =>
>  > '/api/rest/rest_base' } },
>  >       class => 'RestTestDB::CD',
>  >       create_requires => ['artist', 'title', 'year' ],
>  >       update_allows => ['title', 'year']
>  >       );
>  >
>  > And this gets you the following endpoints to fire requests at:
>  >     /api/rest/cd/create
>  >     /api/rest/cd/id/[cdid]/update
>  >     /api/rest/cd/id/[cdid]/delete
>  >     /api/rest/cd/id/[cdid]/add_to_rel/[relation]
>  >     /api/rest/cd/id/[cdid]/remove_from_rel/[relation]
>
>  This is RPC, not REST.  Not that there's anything wrong with that.
>
>  It sounds like what you want to write is a Controller that proxies class
>  methods to a URI.  For example, you write a class like this:
>
>   package Foo;
>
>   sub create { my ($class, $username, $password) = @_; ... }
>   sub delete { my $self = shift; $self->delete }
>   sub foo    { my ($self, $quux, $value_for_42) = @_; ... }
>
>   sub fetch_existing { my ($class, $id) = @_ }
>
>   ...
>   1;
>
>  Then you write a controller like this:
>
>   package MyApp::Controller::Foo;
>   use base 'The::Thing::You're::Writing';
>
>   __PACKAGE__->config(
>         class           => 'Foo',
>         fetch_existing  => 'fetch_existing',
>         new_instance    => 'create',
>         methods         => {
>           create => ['username', 'password'],
>           delete => [],
>           foo    => ['quux', '42'],
>         },
>   );
>   1;
>
>  Then you have actions like:
>
>   /foo//create/<username>/<password>
>   /foo/<id>
>   /foo/<id>/foo/<quux>/<value for 42>
>   /foo/<id>/delete
>
>  In your configuration, an option would be available to REST-ify certain
>  parts of the RPC interface:
>
>   rest => {
>     create => 'create',
>     get    => 'fetch_existing',
>     delete => 'delete',
>     update => 'update',
>   }
>
>  Then you would have the /foo and /foo/<id> REST endpoints do the same
>  thing as the RPC calls.
>

I think I'd prefer to use query parameters like I already do rather
than having them in the URI. In fact what I think I should do is leave
the module as it is but make the verb actions private and write the
base action to distribute based on request type so it can be called
REST. Then, because REST isn't always ideal, create a very slim
subclass which gives the Private methods URIs and call this the RPC
version.

>  Anyway, making this specific to DBIx::Class sounds like a waste of time.
>

Yes, ideally the general parts would be put in a non-DBIC specific
base controller which $whatever can plug into.

However, a DBIC specific module will allow the bulk of the validation
to be done automatically based on column definitions, foreign keys
etc. Also, a powerful list method can be implemented which allows for
complex search conditions via $rs->search for retrieving a subset of
objects, related rows and so forth. I think stuff like this has to be
DBIC specific.

>  Regards,
>  Jonathan Rockway
>
>  --
>  print just => another => perl => hacker => if $,=$"
>
>
>
>  _______________________________________________
>  List: Catalyst at lists.scsys.co.uk
>  Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
>  Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
>  Dev site: http://dev.catalyst.perl.org/
>



More information about the Catalyst mailing list