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 <[EMAIL PROTECTED]> 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 <[EMAIL PROTECTED]> 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, [EMAIL PROTECTED]); >>>> 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 => >>>> [EMAIL PROTECTED], >>>> distinct => >> 1, >>>> order_by => >>>> [EMAIL PROTECTED]) >>>> ); >>>> $self->out($c, [EMAIL PROTECTED]); >>>> 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: [email protected] >> Listinfo: >> http://lists.rawmode.org/mailman/listinfo/catalyst >> Searchable archive: >> > http://www.mail-archive.com/[email protected]/ >> 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 > <Rest.pm> > _______________________________________________ > List: [email protected] > Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst > Searchable archive: http://www.mail-archive.com/ > [email protected]/ > Dev site: http://dev.catalyst.perl.org/ _______________________________________________ List: [email protected] Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/[email protected]/ Dev site: http://dev.catalyst.perl.org/
