Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I'm in the middle of updating an existing site which is implemented entirely as a CGI::Application script.

I'm struggling to understand how I can easily update it to work in a RESTful method, which I understand means that I should have both logical URIs and sensible use of the request method. So for example I'd expect:

GET http://example.com/products/all

Should return a list of all products.

Similarly, subject to authentication, the following should add a new one:

PUT /etc/passwd http://example.com/products/add

I've been generally familiar with CGI::Application in the past, but I've never had to handle either the PUT, LIST, or DELETE primitives, and I'm not 100% sure how to configure either the CGI::Application section, or the Apache configuration itself. (Does that even need to be mentioned?)

I assume that the return type will be JSON, YAML, or similar, but I expect I can manage fudging that myself ;)<?p>

Replies are listed 'Best First'.
Re: Struggling to understand making CGI::Application RESTFUL
by Your Mother (Archbishop) on Jun 07, 2010 at 22:13 UTC

    I can't help with the dispatch stuff, except to snipe that Catalyst::Controller::REST might make it easy. :) As far as the REST design goes. Try to keep verbs and ranges out of URIs. I'd expect /products by itself to return "all" products or at least take a query arg to do so. PUT *is* add. So-

    GET http://example.com/products/all # becomes GET http://example.com/products # or maybe something like GET http://example.com/products?rows=all # or GET http://example.com/products?from=1;to=-1 # And then PUT /etc/passwd http://example.com/products/add # becomes PUT /etc/passwd http://example.com/products # or maybe better PUT /etc/passwd http://example.com/product

    Unless things have progressed recently, you'll also have to "overload" POST to do the "PUT" work since PUT isn't universally supported.

      Well ... PUT has been supported by CGI (and hence CGI::Application) since version 3.31 -- I know, it was the fine monks here that helped me create the patch! (REST Webservices and CGI.pm). There's probably a CGI::Application plugin to make it really easy but here's how I've been doing rest services with CGI::Application:

      sub setup { my $self = shift; my $cgi = $self->query(); $self->start_mode( $cgi->request_method() ); $self->run_modes( 'PUT' => 'update', 'GET' => 'retrieve', 'POST' => 'create', 'DELETE' => 'delete', ); }

      -derby

        The issue is client-side support and the HTML spec. Some browsers do the right thing now but it's not because they are supposed to as much as they are trying to bridge the gap.

      since PUT isn't universally supported

      PUT has been part of HTTP since 1997 .... oh right, nothing is universally supported, like html4 forms don't support PUT, but html5 forms do ...