The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
NAME
    WWW::Resource - Quickly create a REST style web service.

SYNOPSIS
      package ResourceName;

      use HTTP::Status
      use WWW::Resource;
      @ISA = qw( WWW::Resource );

      sub GET {
        return RC_OK, "Congratulations you have accessed this resource.";
      }

      ResourceName->run;

      =EOF

      In a browser:
      http[s]://localhost/resourcename
  
      Congratulations you have accessed this resource.

DESCRIPTION
    This module ties together a small set of serializers and a FastCGI
    interface to a load balancer, in a convenient package allowing you to
    quickly deploy resources to the network with a bare minimum of coding.
    If you have installed a web server and configured it to use FastCGI -
    which takes about fifteen minutes if you use lighttpd - in about two
    more minutes you can expose a REST-style web service.

    Userspace? No problem. SSL? No problem. Load balancing? Got it covered.

    Please see "INSTALL.REST-FRAMEWORK" in the build directory for more info
    about the full system installation.

    There are two ways to return your response to the caller (a browser or
    other program). You can simply return any Perl data structure, which
    will be serialized into the requested format (XML or JSON or "browser
    prettyprint" format), or you can actually construct a page yourself,
    perhaps even using CGI.pm to help, and return a single string. Any
    single string will be transmitted verbatim (after the headers) to the
    caller.

    To access the resource via a browser or other program, decide which
    serialization format you want and add "format=xml" or "format=json" or
    "format=browser" to the query string part of the URI. For example,
    http://localhost/resourcename?format=browser.

    Whenever you define a GET, PUT, POST, or DELETE function, those will be
    installed automatically as handlers. In fact you can override any HTTP
    method whatsoever, but in practice no one should need more than these
    for a REST style service. These functions will recieve as their only
    argument a hash reference to the parsed query string. For instance, the
    "format=browser" arg will be there, as well as any others. This is only
    for convenience, since these items are available through
    $ENV{QUERY_STRING}.

OVERLOADABLE METHODS
    All HTTP methods are overloadable. In practice you will not need more
    than GET, POST, PUT, and DELETE.

    In addition, ttl() and browserprint can be defined. ttl() should return
    a time-to-live value in seconds. Each of your processes will then exit
    after recieving a request after ttl has been exceeded, and the FastCGI
    process manager will start a new instance. Define browserprint() if you
    want to do your own pretty printing to the browser, ie when your service
    is called with format=browser. The default one is incredibly stupid.

EXAMPLE
    Here is a fully functioning REST style web service, implementing all
    four CRUD operations (create retrieve update delete) via the analogous
    POST GET PUT DELETE http methods. This resource consists of all the
    PATH_INFO / QUERY_STRING pairs it has seen via previous requests, in the
    form of a hash.

      package ResourceName;

      use HTTP::Status
      use WWW::Resource;
      @ISA = qw( WWW::Resource );

      my %resource = (); # no resources yet

      # Time-to-live - default 1 hr - optional. You can 
      # also set this in the load balancer config file, but here
      # is finer-grained control if you need it.
      sub ttl { 60*60 };

      # start the event loop
      ResourceName->run;

      # The above will run as-is, but won't do much.
      # Create the following CRUD-analogous methods for different responses.
  
      # "Retrieve"
      sub GET {

        # Return the specified value, if it exists
        if(exists $resource{$ENV{PATH_INFO}}){
          return RC_OK, $resource{$ENV{PATH_INFO}};
        }

        # No named resource specified? Return them all.
        elsif($ENV{PATH_INFO}){ 
          return RC_OK, \%resource;
        }

        # A named resource that's not there is an error
        return RC_NOT_FOUND;
      }

      # "Update"
      sub PUT {
        my ($rkey, $rval) = ($ENV{PATH_INFO}, $ENV{QUERY_STRING});
        if(exists $resource{$rkey}){
          $resource{$rkey} = $rval;
          return RC_UPDATED;
        }
        $resource{$rkey} = $rval;
        return RC_CREATED;
      }

      # "Create"
      sub POST {
        my ($rkey, $rval) = ($ENV{PATH_INFO}, $ENV{QUERY_STRING});
        $resource{$rkey} = $rval;
        return RC_CREATED;
      }

      # "Delete"
      sub DELETE {
        my ($rkey, $rval) = ($ENV{PATH_INFO}, $ENV{QUERY_STRING});
        if(exists $resource{$rkey}){
          delete $resource{$rkey};
          return RC_DELETED;
        }
        return RC_NOT_FOUND;
      }

  REQUIRES
    A web server with FastCGI support, lighttpd is recommended. FCGI LWP
    JSON XML::Dumper

AUTHOR
    Ira Woodhead, <ira at sweetpota dot to>

COPYRIGHT AND LICENSE
    Copyright (C) 2006 by Ira Woodhead

    This library is free software; you can redistribute it and/or modify it
    under the same terms as Perl itself, either Perl version 5.8.6 or, at
    your option, any later version of Perl 5 you may have available.