[Catalyst] RESTful perl implementations...

John Napiorkowski jjn1056 at yahoo.com
Sat Sep 9 01:03:19 CEST 2006


I'd like something that would be similar to the Google
API (Based on Atom) and would also support JSON for
the feed data.  I also think RPC of some sort is
useful for particular method oriented tasks, certain
things just don't fit well into the REST paradigm (in
my opinion, but don't want to start a flame war :) )

I'd be into meeting up on IRC sometime.  I'm in the
East Coast USA timezone (GMT-5).  What about the rest
of you?  I can meet up during this coming weekend.

--john

--- "J. Shirley" <jshirley at gmail.com> wrote:

> I'm working on a similar thing, except relying
> heavier on JSON-RPC for
> certain things, and a mix of RESTful constructs for
> the rest.
> 
> Maybe an IRC meeting where we can get together and
> compare notes to
> solidify our efforts?
> 
> -J
> 
> On 9/7/06, Garrett Goebel <ggoebel at goebel.ws> wrote:
> > My apologies. I haven't made the time yet to fix
> my code to use an
> > ActionClass. And it doesn't look like I'll have a
> chance to work on
> > things again until this weekend at the earliest.
> >
> > In the mean time, you might consider checking out
> the
> > Jifty::Plugin::REST::Dispatcher in the svn
> repository (http://
> > svn.jifty.org/svn/jifty.org) and the slides from
> the following
> > presentation:
> http://pugs.blogs.com/talks/oscon-rhox.pdf.
> >
> > cheers,
> >
> > Garrett
> >
> >
> > On Sep 7, 2006, at 8:22 AM, John Napiorkowski
> wrote:
> >
> > > I'm not trying to make something as magical as
> > > InstantCRUD, but I'd like to add some RESTful
> matching
> > > and convienence to Catalyst actions.  So I'd
> like to
> > > be able to match on various HTTP method types
> and
> > > preparse XML type bodies by various modules
> (XML::Atom
> > > if it's an atom feed, XML::Simple if it's
> > > application/xml, etc.)
> > >
> > > My goal is to make it easy to build web services
> > > similar to the Google Data API.
> > >
> > > As a side project, but related, I'm working up a
> > > controller to handle different error types, so
> you can
> > > just say
> $c->detach('/errors/method_not_allowed') and
> > > have it give a meaningful response.
> > >
> > > I've attached something I'm working on (which I
> am
> > > sure doesn't work yet :) ) to give you the idea
> of my
> > > direction.  If you think it looks in the same
> ballpark
> > > as your goal we should followup.
> > >
> > > Seems all the cool REST articles are using
> Python or
> > > Ruby, I'd like to give them a reason to use Perl
> > > instead :)
> > >
> > > --john
> > >
> > > --- Garrett Goebel <ggoebel at goebel.ws> wrote:
> > >
> > >> On Sep 6, 2006, at 3:35 PM, John Napiorkowski
> wrote:
> > >>
> > >>> Garrett,
> > >>>
> > >>> Looks like we are working on something
> similar.  I
> > >>> hadn't noticed your postings about two weeks
> about
> > >> (I
> > >>> was in the middle of moving from Beijing back
> to
> > >> the
> > >>> USA and missed about a week of Catalyst
> postings)
> > >> or I
> > >>> might have saved time asking the same
> questions
> > >> you
> > >>> asked.
> > >>>
> > >>> I'm actually doing this as an Action class. 
> Since
> > >> I
> > >>> don't find any additional posts I'm not sure
> your
> > >>> status.  Want to collaborate?  I am also very
> > >>> interested in REST based services and would
> enjoy
> > >>> having someone to bounce ideas off of.
> > >>>
> > >>>
> > >>
> > >> I've just been through something similar.
> Moving
> > >> back to the USA from
> > >> Lima, Peru.
> > >>
> > >> I spent the week following that last post
> dissecting
> > >> InstantCRUD and
> > >> rewriting something similar but RESTful for the
> work
> > >> I've previously
> > >> mentioned. I had to present something that
> kinda
> > >> sorta worked on the
> > >> 28th. Which led to many shortcuts being taken.
> I'm
> > >> still not happy
> > >> with where I'm at. But the last week of
> > >> transitioning back to the
> > >> states and getting the kids into school is
> settling
> > >> down. Reminder to
> > >> self... I still need to send a foreign key
> patch for
> > >>
> > >> DBIx::Class::Schema::Loader::DBI::SQLite to
> Brandon.
> > >>
> > >> I'd be happy to collaborate. I'm fully aware
> that
> > >> I'm unaware of
> > >> Catalyst best practices. And like you, I'd love
> to
> > >> bounce ideas and
> > >> code around.
> > >>
> > >> Perhaps you could start by describing your
> goals and
> > >> your approach in
> > >> more detail. I still need to convert my hacked
> > >> Catalyst::Action into
> > >> an class derived from ActionClass. If I get
> some
> > >> time tomorrow, I'll
> > >> work that up and post some code.
> > >>
> > >> cheers,
> > >>
> > >> Garrett
> > >>
> > >>
> > >>> --- Garrett Goebel <ggoebel at goebel.ws> wrote:
> > >>>
> > >>>> On Aug 22, 2006, at 3:49 AM, Matt S Trout
> wrote:
> > >>>>>> Garrett Goebel wrote:
> > >>>>>>
> > >>>>>> I hacked something into the Path and Regex
> > >>>> dispatchers to get
> > >>>> collective
> > >>>>>> matching on method and path working in the
> > >>>> prototype.
> > >>>>>
> > >>>>> You shouldn't need to hack anything into
> these;
> > >>>> just use a custom
> > >>>> ActionClass
> > >>>>> that overrides $action->match to introspect
> onto
> > >>>> the request
> > >>>> method and
> > >>>>> anything else you need (this is already how
> > >> :Args
> > >>>> is handled, see the
> > >>>>> Catalyst::Action source for the
> implementation).
> > >>>>
> > >>>> Thanks. I'd found the :Args code in
> > >> Catalyst::Action
> > >>>> last night and
> > >>>> managed to shoehorn the request method and
> path
> > >>>> parameter matching
> > >>>> checks into it. How to subclass or override
> it
> > >> was
> > >>>> going to be my
> > >>>> next question. I'll check out using a custom
> > >>>> ActionClass.
> > >>>>
> > >>>> Last night I also sub-classed the Request
> class
> > >> to
> > >>>> add:
> > >>>> __PACKAGE__->mk_accessors(qw/path_parameters
> > >>>> accept_extension/);
> > >>>>
> > >>>> And I'm currently subclassing the Dispatcher
> to
> > >>>> override
> > >>>> prepare_action in order to:
> > >>>> o  remove uri path parameters from
> > >> $c->request->path
> > >>>> and add to
> > >>>>     $c->request->path_parameters
> > >>>> o  remove "file" extension from last path
> segment
> > >>>> and add to
> > >>>>     $c->request->accept_extension
> > >>>> o  filter body parameters from using
> content_type
> > >>>> implied by the
> > >>>>     accept_extension (json, yaml, etc) and
> add to
> > >>>> $c->request-
> > >>>>> parameters.
> > >>>>     Perhaps I should consider just using the
> > >>>> $c->request->content_type?
> > >>>> o  check POST requests for hidden
> > >> _method=DELETE|PUT
> > >>>> parameter and
> > >>>> update
> > >>>>     $c->request->method accordingly
> > >>>>
> > >>>> These are all things I want to do once per
> > >> request,
> > >>>> not once per
> > >>>> action. Certainly there are better places to
> > >> perform
> > >>>> some of these
> > >>>> tasks. And I would like to hear any advice on
> the
> > >>>> best place to
> > >>>> override catalyst for each. In the mean time,
> at
> > >>>> least I've got a
> > >>>> proof of concept working.
> > >>>>
> > >>>>
> > >>>> My controller now is able to look like:
> > >>>>
> > >>>> # GET http://foo.com/model
> > >>>> # GET http://foo.com/model.json
> > >>>> sub index :GET :Path('') Args(0) {
> > >>>>      my ($self, $c) = @_;
> > >>>>      my @models = grep {
> > >>>> UNIVERSAL::can($c->model($_),
> > >>>> 'result_source') }
> > >>>>                   $c->models;
> > >>>>      $self->out($c, \@models);
> > >>>>      1;
> > >>>> }
> > >>>>
> > >>>> # GET http://foo.com/model/Person
> > >>>> sub show :GET :Path('') :Args(1) {
> > >>>>      my ($self, $c, $model) = @_;
> > >>>>      my @pkcols =
> > >>>>
> > >>
> $c->model($model)->result_source->primary_columns;
> > >>>>      my @pk_tuples = map(
> > >>>>          { my $tuple = $_; csv_encode(map({
> > >>>> $tuple->$_ } @pkcols)) }
> > >>>>          $c->model($model)->search(undef,
> > >>>>                                    {columns 
> =>
> > >>>> \@pkcols,
> > >>>>                                     distinct
> =>
> > >> 1,
> > >>>>                                     order_by
> =>
> > >>>> \@pkcols})
> > >>>>      );
> > >>>>      $self->out($c, \@pk_tuples);
> > >>>>      1;
> > >>>> }
> > >>>>
> > >>>> # GET http://foo.com/model/Person;edit
> > >>>> sub edit :GET :Path('') :PathParam(edit)
> :Args(1)
> > >>>> {...}
> > >>>>
> > >>>> # GET http://foo.com/model/Person;add
> > >>>> sub add :GET :Path('') :PathParam(add)
> :Args(1)
> > >>>> {...}
> > >>>>
> > >>>>
> > >>>> # GET http://foo.com/model/Person;column_info
> > >>>> # GET
> > >> http://foo.com/model/Person.yaml;column_info
> > >>>> sub show_column_info :GET :Path('')
> > >>>> :PathParam(column_info) :Args(1) {
> > >>>>      my ($self, $c, $model) = @_;
> > >>>>      my $rs  =
> $c->model($model)->result_source;
> > >>>>      my %column_info = map { $_ =>
> > >>>> $rs->column_info($_)} $rs->columns;
> > >>>>      $self->out($c, \%column_info);
> > >>>>      1;
> > >>>> }
> > >>>>
> > >>>> # POST http://foo.com/model/Person;new
> > >>>> sub create :POST :Path('') :PathParam(new)
> > >> :Args(1)
> > >>>> {...}
> > >>>>
> > >>>> # PUT http://foo.com/model/Person/32
> > >>>> sub update :PUT :Path('') :Args(2) {...}
> > >>>>
> > >>>> # DELETE http://foo.com/model/Person/32
> > >>>> sub destroy :DELETE :Path('') :Args(2) {...}
> > >>>>
> > >>
> > >>
> 
> _______________________________________________
> List: Catalyst at lists.rawmode.org
> Listinfo:
> http://lists.rawmode.org/mailman/listinfo/catalyst
> Searchable archive:
>
http://www.mail-archive.com/catalyst@lists.rawmode.org/
> Dev site: http://dev.catalyst.perl.org/
> 


__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 



More information about the Catalyst mailing list