[Catalyst] Request for comments: model class for REST queries

Adam Jacob adam at stalecoffee.org
Fri Dec 8 05:26:28 GMT 2006


On Thu, Dec 07, 2006 at 03:14:19PM -0500, Christopher Heschong wrote:
> >My first thought is that you are going to need to support the full  
> >range of HTTP Methods.  At the very least, you will need: GET, POST,
> >PUT and DELETE.  You probably want to support OPTIONS and HEAD as
> >well.
> 
> 
> Thanks.  There are ->get and ->post methods already, plus ->request 
> ($method, ...) for any other method LWP supports if you need those.   
> But it's probably a good idea to add them as methods by default.   
> Although what would you really expect to get back from OPTIONS?  I'm  
> sort of expecting some XML or something back now.

The result of an OPTIONS call should be the list of available ways to
ask for a resource.  It should return things like whether it accepts
a GET/POST/PUT/DELETE, what content-types are supported, and other
things.  From the RFC for the OPTIONS method:

   A 200 response SHOULD include any header fields that indicate
   optional features implemented by the server and applicable to that
   resource (e.g., Allow), possibly including extensions not defined by
   this specification. The response body, if any, SHOULD also include
   information about the communication options. The format for such a
   body is not defined by this specification, but might be defined by
   future extensions to HTTP. Content negotiation MAY be used to select
   the appropriate response format. If no response body is included, the
   response MUST include a Content-Length field with a field-value of
   "0".

I think simply returning the headers is a useful thing.  At the very
least, it lest you detect what Verbs (actions) are available for a given
resource, and possibly the different content-types it can be presented
in.

If you look at the source for Test::Rest in the Catalyst::Action::REST 
distribution (t/lib/Test/Rest.pm) you can see some simple closures for
generating these kinds of methods.

> One thought that crossed my mind was to make methods like:
> 
> $c->model('whatever')->get_questionSearch( [params] )
> $c->model('whatever')->post_questionSearch( [params] )
> 
> or just
> 
> $c->model('whatever')->questionSearch( [params] ) #default to GET

I think something like:

c->model('REST')->get(resource => 'questionSearch', params => \%params);
c->model('REST')->put(resource => 'questionSearch', body => $new_question);

Would be totally reasonable.  Then, in a model for a specific service,
you could have things like:

$c->model('FooBar')->questionSearch(); # Does a GET on question search
$c->model('FooBar')->add_questionSearch(); # Does a PUT on questionSearch
$c->model('FooBar')->delete_questionSearch(); # Does a DELETE

> A bit of AUTOLOAD should do the trick, but would the above syntax be  
> better or worse?

I think you make a toolkit that lets people build more specific models
for individual web services, and then provide as much magic around that
as you can.  For example, have the serialization portions be
configurable, provide as many helper methods as make sense, etc.

Adam



More information about the Catalyst mailing list