Re: [Catalyst] Error in subclassing Catalyst::Controller::DBIC::API::REST

2009-06-24 Thread luke saunders
On Wed, Jun 24, 2009 at 3:00 PM, Fitz Elliottfelli...@virginia.edu wrote:
 Hey Amiri,

 Now for the problem. When I go to test this:

   my $mech = Test::WWW::Mechanize::Catalyst-new;
   ok(my $schema = DBICTest-init_schema(), 'got schema');

 my $req = GET(http://localhost/api/rest/artist/list;, {
 }, 'Accept' = 'text/x-json' );
 $mech-request($req);
 cmp_ok( $mech-status, '==', 200, 'open attempt okay' );


 I just finished building some code around C::C::DBIC::API and ran into
 something similar. I'm assuming in this test that you are trying to get a
 list of all artists.  If so, you should make a GET request against
 http://localhost/api/rest/artist.   In a REST controller, artist/list would
 be asking for the artist whose id is 'list'.C::C::DBIC::API also doesn't
 support GET on an individual object out of the box, but it is easy to add.
  Just add

  sub object_GET :Private {}

 in RestTest::ControllerBase::REST.  The rest of the code is already there to
 retrieve the object and serialize it.

As Fitz has said above - if you want to use REST then you have to make
the GET request to just /api/rest/artist. However if you would prefer
to to the url /api/rest/artist/list then that's more RPC style and so
you'd have to be subclassing Catalyst::Controller::DBIC::API::RPC.

I'm interested in the
'//localhost/api/rest/artist/api/rest/artist/object' weirdness. Is
that specific to running under Test::WWW::Mechanize::Catalyst? Maybe
try starting a server in debug mode and then specify
CATALYST_SERVER=http://localhost:3000 before running the test to see
how that's getting dispatched.

Cheers,
Luke.

___
List: Catalyst@lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/


Re: [Catalyst] Testing controller which require login.

2009-05-13 Thread luke saunders
On Wed, May 13, 2009 at 6:07 AM, Louis Erickson lerick...@rdwarf.net wrote:

 I've been neglecting my test scripts, and I'm finally getting to that
 before my app gets any bigger.  I want to make sure I don't break anything
 that's working, and that it works as well as I think it does.

 I'm probably going to have several questions in the next few days about
 tests.  I think I've got a lot of the basics working; tests pass, I have a
 sensible test database and environment.  I can see fixtures from here, I
 think.

 I haven't been able to get a test user logging in and out yet, though.

 I have several sections of my application that redirect the user away if
 they are not logged in.  I have another that returns a 404 if they don't
 have access, so prying users can't find it (as easily).

 My tests are currently based on the stubs generated by myapp_create,
 and use Catalyst::Test.  I could move them to WWW::Mechanize::Catalyst if
 it would help.

 I can't tell if Catalyst::Test supports cookies.  Does it?  Or do I need
 to use WWW::Mechanize::Catalyst for that?

 I've read some suggestions on how to go about this, and found a couple.

 1 Use WWW::Mechanize::Catalyst to log the user in
 2 Use the mock user in config to set a user who is logged in.

 The problem with really logging the user in is that the login is a set of
 site-wide cookies generated by a Single Sign On system.  That system may
 or may not have a test instance running.  If it does, cookies stored from
 it probably won't work with cookies from 'localhost' like the local test
 app wants.

 I can set a mock user, but then that user is always logged in.  Can that
 mock user be changed by the test scripts, so I can have them log out, log
 in as an administrator, log in as an unprivileged user, etc, and test the
 pages perform correctly?  If so, I've missed that - it would work, I
 think.

 The SSO is available to me as a library.  I'm considering adding a login
 page to the application, so the test scripts can log in to the SSO through
 the application and solve the problem.  Is duplicating a little code (not
 much, most of it is in a module) to make tests work a good idea?

 I'd want the application-specific login page to only be available while
 the test scripts are running.  In production it shouldn't exist or at the
 worst redirect back to the real SSO login page.  Writing a function which
 behaves differently in test seems like a source of errors to me.  Does
 this sound possible?

 Can I just generate the cookie and put it in the cookie store directly
 before the query is made to the application?  I can generate the cookie
 with the SSO library.  I don't see a way to do that through either test
 tool.

 I'm trying to learn and do this in a maintainable, sensible way.  Any help
 you can give is highly appreciated.

I'm not sure I really understand what's quite so complicated about the
SSO. It sounds like it validates some credentials and then sets some
site cookies if successful, which is pretty standard and should work
with the following testing method. If not then please eleborate.

You need a set of fixtures (test dataset) and a test database to
deploy them to. At the start of every test you should populate your
test database with these fixtures.

Test::WWW::Mechanize::Catalyst can handle cookies just fine and
posting to forms is easy enough, which means you can easily use it to
test login.

Here's an example .t file (assumes DBIx::Class, but the principle is
the same for anything):

use strict;
use warnings;

use lib 't/lib';

use MyAppTest;
use Test::More tests = 1;
use Test::WWW::Mechanize::Catalyst 'MyApp';
use HTTP::Request::Common;

my $base = 'http://localhost';
my $mech = Test::WWW::Mechanize::Catalyst-new;

# populate test database with fixtures and get a DBIC schema in return
my $schema = MyAppTest-init_schema({ set = 'sample' });

{
  my $req = POST( $base/login, {
username = 'testuser',
password = 'testpassword',
  });
  $mech-request($req, $content_type);
  cmp_ok( $mech-status, '==', 200, 'Login successful' );
}

# if all goes well at this point $mech will be logged in.

.


package MyAppTest;

use strict;
use warnings;

BEGIN {
  # so that the app uses the test config and therefore test database
  $ENV{ MYAPP_CONFIG_LOCAL_SUFFIX } = 'test';
}

use MyApp::Util::Fixtures;

sub init_schema {
  my ($class, $args) = @_;

  my $myapp_fixtures = MyApp::Util::Fixtures-new;
  $myapp_fixtures-populate({ schema = 'TestDB', set = ($args-{set}
|| 'default') });
  my $schema = $myapp_fixtures-schema;
  return $schema;
}

I put the gritty business of populating the database from fixtures in
MyApp::Util::Fixtures. I use DBIx::Class::Fixtures for all this and
have some sample code if you need it.

___
List: Catalyst@lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
Dev 

[Catalyst] Announce: Catalyst::Controller::DBIC::API 1.002000

2009-03-19 Thread luke saunders
Yesterday I uploaded a new version of Catalyst::Controller::DBIC::API
which addresses a couple of RT issues* and also provides some new
features. Here's the change log.

- Better error handing when unable to parse search arg
- Added setup_dbic_args_method config option
- Added list_search_exposes config option
- Fixed searches on columns which have a rel with the same name and vice versa
- Added search by json
- Added pagination support

Thanks,
Luke.

* https://rt.cpan.org/Ticket/Display.html?id=43964
* https://rt.cpan.org/Ticket/Display.html?id=44010

___
List: Catalyst@lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/


[Catalyst] Very long request time weirdness

2008-06-24 Thread luke saunders
In order to get some info on how long requests were taking and where
the bottlenecks were we put some code into MyApp::finalize which wrote
info gained from $c-stats to the DB so we could easily check them
later (code given below). Occasionally we get a request where total
time ($c-stats-elapsed) is very long (more than 50 seconds) but each
individual action executes very quickly (they usually sum to less than
1 second). So presumably something is happening between the end action
and finalize which is taking ages, but what on earth could that be?

This is Catalyst::Runtime 5.7014 running on a Fastcgi system. This
only affects about 3 out of 35000 requests, but I'd still like to know
why it's happening. Any ideas?

sub finalize {
  my $c = shift;

  $c-NEXT::finalize( $c, @_ );
  return if $c-_static_file; # don't bother logging the serving of
static files
  return unless $c-config-{request_logging};

  my $request_log = {
browser = $c-req-browser-browser_string(),
browser_version = $c-req-browser-version(),
path = join('', '/', $c-req-path),
params = join('', map { $_ . = . $c-req-params-{$_} } keys
%{$c-req-params}),
total_time = $c-stats-elapsed,
total_sql_time = sprintf('%0.6f',
$c-model('123peopleDB')-querylog-time_elapsed),
query_count = $c-model('123peopleDB')-querylog-count
  };
  my $log_req_obj = $c-model('123peopleDB::LogRequest')-create($request_log);

  my @request_stages = $c-stats-report;
  foreach my $stage (@request_stages) {
my $request_stage_log = {
  depth = $stage-[0],
  stage_name = ($stage-[3] ? '(Action) ' : '(Other) ') . $stage-[1],
  total_time = $stage-[2],
  total_sql_time = 0,
  query_count = 0
};
$log_req_obj-related_resultset('stages')-create($request_stage_log);
  }
}

___
List: Catalyst@lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/


Re: [Catalyst] Re: RFC: Catalyst::Controller::REST::DBIC

2008-05-05 Thread luke saunders
On Mon, May 5, 2008 at 1:20 AM, Patrick Donelan [EMAIL PROTECTED] wrote:

  No, but how you provide an alternative to full RESTness for clients that
  don't handle the full range of HTTP verbs -is- a matter for discussion.
 

 Which clients are we talking about here? I did a quick google search and
 could only find an off-hand remark along the lines of in 2006 safari had
 poor support for REST verbs. I'm interested because in my own personal
 experience I haven't run into any problems generating PUT/POST/GET/DELETE
 with IE/FF/Opera browsers. Or are you talking about the inability to specify
 anything other than GET or POST as a form method?


I'm afraid I can't remember exactly, it was around two years ago and
we needed to fire PUT requests using XHR in JS using Dojo and it just
wasn't happening. Dojo has changed dramatically since then and now has
an xhrPut method so I expect whatever the problem has been addressed.

___
List: Catalyst@lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/


Re: [Catalyst] RFC: Catalyst::Controller::REST::DBIC

2008-05-05 Thread luke saunders
On Mon, May 5, 2008 at 5:19 PM, J. Shirley [EMAIL PROTECTED] wrote:
 On Mon, May 5, 2008 at 8:18 AM, Andrew Rodland [EMAIL PROTECTED] wrote:
   On Monday 05 May 2008 09:50:08 am J. Shirley wrote:
 On Mon, May 5, 2008 at 4:31 AM, Matt S Trout [EMAIL PROTECTED] wrote:
  On Sun, May 04, 2008 at 09:06:30AM -0700, J. Shirley wrote:
  
  I fail to see how whether the PK is the lookup key or not has any
   relevance at all to the original point, which was your lookup key 
 and
   names of actions might clash so it can be nice to have an extra path
  component such as 'id' for the lookup part to disambiguate.

 Because I'm talking about REST and a verb in the URI doesn't need to be
 there.
  
But those nouns you're talking about aren't verbs at all.
  
Andrew

  How is /create, /edit or /delete not a verb?
  My argument is separate to the /create is valid in the /foo/{token}
  bit.  I'm saying that /foo/create is silly to have in the first place ...

Okay, let me clear this up. Originally the plan was to have a
centralised REST-style action which dispatched POST/PUT/GET/DELETE
requests to the appropriate actions while also providing RPC-style
verb actions as an alternative for use if the client didn't properly
support the REST request methods. Having listened to discussion in
this thread I think it would be better to make the module pure REST
and then provide the RPC alternative through a subclass, perhaps also
integrating Catalyst::Request::REST::ForBrowsers into the REST version
as suggested.

  If you apply actual REST principles, you don't have such nonsense.
  But again, as I said, this is if you are working with REST.  If REST
  doesn't fit your application model, don't use it.  Just don't name
  things REST when they are really CRUD.

Why can't CRUD be RESTful?

In fact my revised plan is to glue together a base REST module and a
base CRUD module and add the list method discussed somewhere else in
this thread to provide a complete default RESTful module. Ideally the
REST base module could be swapped for an RPC style base module to
easily provide an RPC alternative of the same thing.

___
List: Catalyst@lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/


Re: [Catalyst] RFC: Catalyst::Controller::REST::DBIC

2008-05-05 Thread luke saunders
On Mon, May 5, 2008 at 7:28 PM, Peter Karman [EMAIL PROTECTED] wrote:


  On 05/05/2008 12:16 PM, J. Shirley wrote:

  
   The discussions about a better CRUD base class with REST and RPC
   adapters is obviously the better (best?) solution, but I also think
   there will be significant disagreement between appropriate URI
   resource conventions (as my exchange with zby is an example of.)

  As has been mentioned before, there is an existing REST + CRUD 
 implementation already on CPAN:

  http://search.cpan.org/dist/CatalystX-CRUD/lib/CatalystX/CRUD/REST.pm


Out of interest, why did you not use Catalyst::Controller::REST here?

  It definitely has URI styles in place already, though overriding fetch() to 
 chain to a
  different root (like /id instead of /) seems trivial to me.

  There is also work started on a DBIC adapter, and existing model stores in 
 place already
  for RDBO and filesystem (LDAP is on my TODO list). SVN is here:

  http://dev.catalyst.perl.org/repos/Catalyst/CatalystX-CRUD/

  I hope to push a new release of CX::CRUD soon that will support the 
 'x-tunneled-method'
  syntax of drolsky's REST::ForBrowsers in addition to the '_http_method' 
 syntax of prior
  CX::CRUD::REST releases.

  Please, consider building on existing code like CX::CRUD and/or suggesting 
 changes to the
  current implementation, rather than starting a new project. There are 
 already too many
  CRUD-style Catalyst modules on CPAN imho.

  --
  Peter Karman  .  [EMAIL PROTECTED]  .  http://peknet.com/




  ___
  List: Catalyst@lists.scsys.co.uk
  Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
  Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
  Dev site: http://dev.catalyst.perl.org/


___
List: Catalyst@lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/


Re: [Catalyst] RFC: Catalyst::Controller::REST::DBIC

2008-05-05 Thread luke saunders
On Mon, May 5, 2008 at 6:16 PM, J. Shirley [EMAIL PROTECTED] wrote:

 On Mon, May 5, 2008 at 9:51 AM, luke saunders [EMAIL PROTECTED] wrote:
   On Mon, May 5, 2008 at 5:19 PM, J. Shirley [EMAIL PROTECTED] wrote:
 On Mon, May 5, 2008 at 8:18 AM, Andrew Rodland [EMAIL PROTECTED] 
 wrote:
   On Monday 05 May 2008 09:50:08 am J. Shirley wrote:
 On Mon, May 5, 2008 at 4:31 AM, Matt S Trout [EMAIL PROTECTED] 
 wrote:
  On Sun, May 04, 2008 at 09:06:30AM -0700, J. Shirley wrote:
  
  I fail to see how whether the PK is the lookup key or not has 
 any
   relevance at all to the original point, which was your lookup 
 key and
   names of actions might clash so it can be nice to have an 
 extra path
  component such as 'id' for the lookup part to disambiguate.

 Because I'm talking about REST and a verb in the URI doesn't need 
 to be
 there.
  
But those nouns you're talking about aren't verbs at all.
  
Andrew

  How is /create, /edit or /delete not a verb?
  My argument is separate to the /create is valid in the /foo/{token}
  bit.  I'm saying that /foo/create is silly to have in the first place 
 ...
  
Okay, let me clear this up. Originally the plan was to have a
centralised REST-style action which dispatched POST/PUT/GET/DELETE
requests to the appropriate actions while also providing RPC-style
verb actions as an alternative for use if the client didn't properly
support the REST request methods. Having listened to discussion in
this thread I think it would be better to make the module pure REST
and then provide the RPC alternative through a subclass, perhaps also
integrating Catalyst::Request::REST::ForBrowsers into the REST version
as suggested.
  
  
  If you apply actual REST principles, you don't have such nonsense.
  But again, as I said, this is if you are working with REST.  If REST
  doesn't fit your application model, don't use it.  Just don't name
  things REST when they are really CRUD.
  
Why can't CRUD be RESTful?
  
In fact my revised plan is to glue together a base REST module and a
base CRUD module and add the list method discussed somewhere else in
this thread to provide a complete default RESTful module. Ideally the
REST base module could be swapped for an RPC style base module to
easily provide an RPC alternative of the same thing.
  

  REST and CRUD are not mutually exclusive, but implementations can be.

  When I see things like /book/create, /book/1/edit I see CRUD (or RPC)
  but not REST.  REST also doesn't have to be CRUD.  I have a REST
  application that is more CR.  It just posts immutable records and
  provides findability on those records.

  The discussions about a better CRUD base class with REST and RPC
  adapters is obviously the better (best?) solution, but I also think
  there will be significant disagreement between appropriate URI
  resource conventions (as my exchange with zby is an example of.)  I
  haven't had enough time to actually proffer any code, but since this
  is a central focus of my development as late I'm very opinionated in
  these matters :)

I think that the /foo/{token} vs /foo/id/{token} is the only point of
contention. And it would definitely be nice if an agreement could be
reached on this. Indeed, if I do develop this further it would make
sense if the REST base class is your own
Catalyst::Controller::REST::DBIC::Item.

To me the /foo/{token} URI is only acceptable if it is understood that
no further custom object level URIs can then be added
(/foo/{token}/disable for example) and that lookup can only ever be by
{token} rather than {name} or something else. For REST I can see that
this is possible but I do feel that putting something between the base
and the token to clearly identify it as object level is generally the
safest option.

Peter made a fair point that if you don't like it you can subclass and
change, but agreeing on a best practice and making that default is
obviously desirable.

  I just want to be an advocate of standards and not slip into the
  Internet Explorer Development Methodology.  Eventually browsers will
  support this stuff, in the mean time, using strict REST makes
  webservices so much easier.



  ___
  List: Catalyst@lists.scsys.co.uk
  Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
  Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
  Dev site: http://dev.catalyst.perl.org/


___
List: Catalyst@lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/


Re: [Catalyst] RFC: Catalyst::Controller::REST::DBIC

2008-05-05 Thread luke saunders
On Mon, May 5, 2008 at 9:29 PM, J. Shirley [EMAIL PROTECTED] wrote:

 On Mon, May 5, 2008 at 1:10 PM, luke saunders [EMAIL PROTECTED] wrote:
  
   On Mon, May 5, 2008 at 6:16 PM, J. Shirley [EMAIL PROTECTED] wrote:

 On Mon, May 5, 2008 at 9:51 AM, luke saunders [EMAIL PROTECTED] wrote:
   On Mon, May 5, 2008 at 5:19 PM, J. Shirley [EMAIL PROTECTED] wrote:
 On Mon, May 5, 2008 at 8:18 AM, Andrew Rodland [EMAIL 
 PROTECTED] wrote:
   On Monday 05 May 2008 09:50:08 am J. Shirley wrote:
 On Mon, May 5, 2008 at 4:31 AM, Matt S Trout [EMAIL 
 PROTECTED] wrote:
  On Sun, May 04, 2008 at 09:06:30AM -0700, J. Shirley 
 wrote:
  
  I fail to see how whether the PK is the lookup key or not 
 has any
   relevance at all to the original point, which was your 
 lookup key and
   names of actions might clash so it can be nice to have 
 an extra path
  component such as 'id' for the lookup part to 
 disambiguate.

 Because I'm talking about REST and a verb in the URI 
 doesn't need to be
 there.
  
But those nouns you're talking about aren't verbs at all.
  
Andrew

  How is /create, /edit or /delete not a verb?
  My argument is separate to the /create is valid in the 
 /foo/{token}
  bit.  I'm saying that /foo/create is silly to have in the first 
 place ...
  
Okay, let me clear this up. Originally the plan was to have a
centralised REST-style action which dispatched POST/PUT/GET/DELETE
requests to the appropriate actions while also providing RPC-style
verb actions as an alternative for use if the client didn't properly
support the REST request methods. Having listened to discussion in
this thread I think it would be better to make the module pure REST
and then provide the RPC alternative through a subclass, perhaps 
 also
integrating Catalyst::Request::REST::ForBrowsers into the REST 
 version
as suggested.
  
  
  If you apply actual REST principles, you don't have such 
 nonsense.
  But again, as I said, this is if you are working with REST.  If 
 REST
  doesn't fit your application model, don't use it.  Just don't 
 name
  things REST when they are really CRUD.
  
Why can't CRUD be RESTful?
  
In fact my revised plan is to glue together a base REST module and a
base CRUD module and add the list method discussed somewhere else in
this thread to provide a complete default RESTful module. Ideally 
 the
REST base module could be swapped for an RPC style base module to
easily provide an RPC alternative of the same thing.
  

  REST and CRUD are not mutually exclusive, but implementations can be.

  When I see things like /book/create, /book/1/edit I see CRUD (or RPC)
  but not REST.  REST also doesn't have to be CRUD.  I have a REST
  application that is more CR.  It just posts immutable records and
  provides findability on those records.

  The discussions about a better CRUD base class with REST and RPC
  adapters is obviously the better (best?) solution, but I also think
  there will be significant disagreement between appropriate URI
  resource conventions (as my exchange with zby is an example of.)  I
  haven't had enough time to actually proffer any code, but since this
  is a central focus of my development as late I'm very opinionated in
  these matters :)
  
I think that the /foo/{token} vs /foo/id/{token} is the only point of
contention. And it would definitely be nice if an agreement could be
reached on this. Indeed, if I do develop this further it would make
sense if the REST base class is your own
Catalyst::Controller::REST::DBIC::Item.

  If people are ok with the verbs being in the URL as a sacrifice to
  broken browsers, agreed :)

I think the consensus is probably the opposite. I already agreed that
the verbs shouldn't be in the REST module but there should be an RPC
variant.

  I'm going to be rounding out the tests for my work, and I'm giving a
  talk on it at YAPC::Asia.  It's mostly just my thoughts on how things
  go, but the work is from a web-services point of view, with some
  browser views.  I'll post my slides up (and there may be video fo the
  talk) afterwards.

Nice.

To me the /foo/{token} URI is only acceptable if it is understood that
no further custom object level URIs can then be added
(/foo/{token}/disable for example) and that lookup can only ever be by
{token} rather than {name} or something else. For REST I can see that
this is possible but I do feel that putting something between the base
and the token to clearly identify it as object level is generally the
safest option.

  I like to map

Re: [Catalyst] RFC: Catalyst::Controller::REST::DBIC

2008-05-04 Thread luke saunders
On Sun, May 4, 2008 at 10:20 AM, Zbigniew Lukasiak [EMAIL PROTECTED] wrote:

 On Sun, May 4, 2008 at 2:38 AM, luke saunders [EMAIL PROTECTED] wrote:
   I have started to write a Catalyst base controller for REST style CRUD
via DBIC. I have noticed that a number of other people have been
working on or are thinking about working on something similar, most
notabley J. Shirley who seems to be creating
Catalyst::Controller::REST::DBIC::Item

 (http://dev.catalystframework.org/svnweb/Catalyst/browse/Catalyst-Controller-REST-DBIC-Item/)
and some chaps from a recent thread on this list (entitled
Dispatching with Chained vs HTTP method).
  
Ideally I would like to merge J. Shirley's effort into mine (or visa
versa) along with anything that anyone else has. Basically I want to
avoid ending up with a load of modules that all do the same thing.
  
My effort is heavily based on something mst wrote a while ago, and
since then I've ended up writing something very similar for every
project I've worked on which indicates it's worth OSing. Essentially
it is used like so:
  
 package MyApp::Controller::API::REST::CD;
  
 use base qw/Catalyst::Controller::REST::DBIC/;
  
 ...
  
 __PACKAGE__-config
   ( action = { setup = { PathPart = 'cd', Chained =
'/api/rest/rest_base' } },
 class = 'RestTestDB::CD',
 create_requires = ['artist', 'title', 'year' ],
 update_allows = ['title', 'year']
 );
  
And this gets you the following endpoints to fire requests at:
   /api/rest/cd/create
   /api/rest/cd/id/[cdid]/update
   /api/rest/cd/id/[cdid]/delete
   /api/rest/cd/id/[cdid]/add_to_rel/[relation]
   /api/rest/cd/id/[cdid]/remove_from_rel/[relation]
  
The full source is here:

 http://lukesaunders.me.uk/dists/Catalyst-Controller-REST-DBIC-1.00.tar.gz
  
If you have a few moments please have a look, especially if you are
working on something similar. Today I even wrote a test suite which
has a test app and is probably the best place to look to see what it
does.

  I've been planning for a more REST-like update to InstantCRUD for a
  long time.  My approach is a bit different because for validation and
  for generating form's HTML I use HTML::Widget.  I believe validation
  is important and separate enough to have a separate package (and I
  don't want to reinvent the wheel - so I use what is available at
  CPAN).  I also choose to generate the HTML - because I believe there
  is too much logic (classes for errors, options from the database,
  subforms from the database - see below) in it for the simplistic
  Template::Toolkit language - an elegant solution for that could be
  also a TT plugin.

  Now I am working on porting Instant to use Rose::HTML::Form instead of
  HTML::Wiget - it will give it much more solid base.


I thinking generating the form is a step too far for this sort of
thing, normally I just want the API. In some cases I'll be generating
the form HTML with Jemplate for example.

  One more difference in my approach is that the 'update' action will be
  able to edit not just one row from the DB - but all the interrelated
  records that together make a full object.  This means also adding and
  removing the related records - so I'll not have the add_to_rel
  remove_from_rel actions.


Interesting. How are you representing the related objects in the request?

  There is also an effort by Peter Carman:
  http://search.cpan.org/~karman/CatalystX-CRUD-0.25/lib/CatalystX/CRUD/REST.pm
  - and I more or less agreed with Peter on some basics - so that
  hopefully our code will be compatible and maybe even will form
  together just one solution.

  Finally I am waiting for the Moose port of Catalyst - so that all the
  CRUD functionality could be just a Role instead of forcing the user to
  'use base'.


  
Note that it lacks:
- list and view type methods which dump objects to JSON (or whatever)
- clever validation - it should validate based on the DBIC column
definitions but it doesn't
- any auth - not sure if it should or not, but it's possible
  
Also it doesn't distinguish between POST, PUT, DELETE and GET HTTP
requests favouring instead entirely separate endpoints, but that's up
for discussion.
  
So, J. Shirley, do you have any interest in a merge? And others, do
you have ideas and would you like to contribute?
  
Thanks,
Luke.
  


   ___
List: Catalyst@lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: 
 http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/
  



  --
  Zbigniew Lukasiak
  http://brudnopis.blogspot.com/

  ___
  List: Catalyst@lists.scsys.co.uk
  Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman

Re: [Catalyst] RFC: Catalyst::Controller::REST::DBIC

2008-05-04 Thread luke saunders
On Sun, May 4, 2008 at 2:18 PM, Jonathan Rockway [EMAIL PROTECTED] wrote:
 * On Sat, May 03 2008, luke saunders wrote:
 __PACKAGE__-config
   ( action = { setup = { PathPart = 'cd', Chained =
   '/api/rest/rest_base' } },
 class = 'RestTestDB::CD',
 create_requires = ['artist', 'title', 'year' ],
 update_allows = ['title', 'year']
 );
  
   And this gets you the following endpoints to fire requests at:
   /api/rest/cd/create
   /api/rest/cd/id/[cdid]/update
   /api/rest/cd/id/[cdid]/delete
   /api/rest/cd/id/[cdid]/add_to_rel/[relation]
   /api/rest/cd/id/[cdid]/remove_from_rel/[relation]

  This is RPC, not REST.  Not that there's anything wrong with that.

  It sounds like what you want to write is a Controller that proxies class
  methods to a URI.  For example, you write a class like this:

   package Foo;

   sub create { my ($class, $username, $password) = @_; ... }
   sub delete { my $self = shift; $self-delete }
   sub foo{ my ($self, $quux, $value_for_42) = @_; ... }

   sub fetch_existing { my ($class, $id) = @_ }

   ...
   1;

  Then you write a controller like this:

   package MyApp::Controller::Foo;
   use base 'The::Thing::You're::Writing';

   __PACKAGE__-config(
 class   = 'Foo',
 fetch_existing  = 'fetch_existing',
 new_instance= 'create',
 methods = {
   create = ['username', 'password'],
   delete = [],
   foo= ['quux', '42'],
 },
   );
   1;

  Then you have actions like:

   /foo//create/username/password
   /foo/id
   /foo/id/foo/quux/value for 42
   /foo/id/delete

  In your configuration, an option would be available to REST-ify certain
  parts of the RPC interface:

   rest = {
 create = 'create',
 get= 'fetch_existing',
 delete = 'delete',
 update = 'update',
   }

  Then you would have the /foo and /foo/id REST endpoints do the same
  thing as the RPC calls.


I think I'd prefer to use query parameters like I already do rather
than having them in the URI. In fact what I think I should do is leave
the module as it is but make the verb actions private and write the
base action to distribute based on request type so it can be called
REST. Then, because REST isn't always ideal, create a very slim
subclass which gives the Private methods URIs and call this the RPC
version.

  Anyway, making this specific to DBIx::Class sounds like a waste of time.


Yes, ideally the general parts would be put in a non-DBIC specific
base controller which $whatever can plug into.

However, a DBIC specific module will allow the bulk of the validation
to be done automatically based on column definitions, foreign keys
etc. Also, a powerful list method can be implemented which allows for
complex search conditions via $rs-search for retrieving a subset of
objects, related rows and so forth. I think stuff like this has to be
DBIC specific.

  Regards,
  Jonathan Rockway

  --
  print just = another = perl = hacker = if $,=$



  ___
  List: Catalyst@lists.scsys.co.uk
  Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
  Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
  Dev site: http://dev.catalyst.perl.org/


___
List: Catalyst@lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/


[Catalyst] RFC: Catalyst::Controller::REST::DBIC

2008-05-03 Thread luke saunders
I have started to write a Catalyst base controller for REST style CRUD
via DBIC. I have noticed that a number of other people have been
working on or are thinking about working on something similar, most
notabley J. Shirley who seems to be creating
Catalyst::Controller::REST::DBIC::Item
(http://dev.catalystframework.org/svnweb/Catalyst/browse/Catalyst-Controller-REST-DBIC-Item/)
and some chaps from a recent thread on this list (entitled
Dispatching with Chained vs HTTP method).

Ideally I would like to merge J. Shirley's effort into mine (or visa
versa) along with anything that anyone else has. Basically I want to
avoid ending up with a load of modules that all do the same thing.

My effort is heavily based on something mst wrote a while ago, and
since then I've ended up writing something very similar for every
project I've worked on which indicates it's worth OSing. Essentially
it is used like so:

  package MyApp::Controller::API::REST::CD;

  use base qw/Catalyst::Controller::REST::DBIC/;

  ...

  __PACKAGE__-config
( action = { setup = { PathPart = 'cd', Chained =
'/api/rest/rest_base' } },
  class = 'RestTestDB::CD',
  create_requires = ['artist', 'title', 'year' ],
  update_allows = ['title', 'year']
  );

And this gets you the following endpoints to fire requests at:
/api/rest/cd/create
/api/rest/cd/id/[cdid]/update
/api/rest/cd/id/[cdid]/delete
/api/rest/cd/id/[cdid]/add_to_rel/[relation]
/api/rest/cd/id/[cdid]/remove_from_rel/[relation]

The full source is here:
http://lukesaunders.me.uk/dists/Catalyst-Controller-REST-DBIC-1.00.tar.gz

If you have a few moments please have a look, especially if you are
working on something similar. Today I even wrote a test suite which
has a test app and is probably the best place to look to see what it
does.

Note that it lacks:
- list and view type methods which dump objects to JSON (or whatever)
- clever validation - it should validate based on the DBIC column
definitions but it doesn't
- any auth - not sure if it should or not, but it's possible

Also it doesn't distinguish between POST, PUT, DELETE and GET HTTP
requests favouring instead entirely separate endpoints, but that's up
for discussion.

So, J. Shirley, do you have any interest in a merge? And others, do
you have ideas and would you like to contribute?

Thanks,
Luke.

___
List: Catalyst@lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/


Re: [Catalyst] implementing ajax

2008-03-12 Thread luke saunders
On Wed, Mar 12, 2008 at 4:53 PM, Matt Pitts [EMAIL PROTECTED] wrote:
  -Original Message-
   From: Jonathan Rockway [mailto:[EMAIL PROTECTED]
   Sent: Wednesday, March 12, 2008 12:12 PM
   To: The elegant MVC web framework

  Subject: Re: [Catalyst] implementing ajax
  
   * On Wed, Mar 12 2008, Matt Pitts wrote:
The main reason against JSON for me is security. Something that can
   be
eval'd is very dangerous and I'm sure we're all aware of the cross-
   site
vulnerabilities that take advantage of JSON returned data.
  
   Don't parse JSON with eval.  Use a parser.  (How do you think Perl
   parses JSON?)
   It's a code vs. data issue.  Yes, evalling code is dangerous.  So
  don't
   do that.  Treat your data as data and you won't have a problem.

  Sure, I can do this in my own client-side JS, but what if I can't trust
  the client? Even if my returned JSON is purely JSON structure (no var x
  = { JSON DATA };, just { JSON DATA }) can I still be guaranteed
  that if someone does:

  script type=text/javascript
  src=http://myapp.com/some/cat/action/that/returns/json/data;/script

  in their own pages that the local JS engine won't actually put my data
  (with potential user info) into memory and allow a malicious person to
  get it? I see where you could maybe make this same argument against XML,
  but since JSON is really, really close to being eval-able as JS code
  whereas XML is not, I'd rather err on the side of caution.

Just use server side auth for sensitive data. Using a format that's
slightly harder to parse is no protection at all.

  If data is data and you have to use a parser anyway, then again, why not
  use a format that is less vulnerable to malicious access?

___
List: Catalyst@lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/


Re: [Catalyst] implementing ajax

2008-03-11 Thread luke saunders
On Mon, Mar 10, 2008 at 4:37 PM, Jennifer Ahn [EMAIL PROTECTED] wrote:
 hello!

  i'm wondering how one would implement the server side controller end of
  an application with ajax.  i have the javascript on my client sending an
  xml file to a uri controller method but, how does the controller process
  that xml?  is the standard way of doing this by reading in the xml file
  through stdin?  i'd like to implement this without using JSON of jemplate.

  thanks for your help!

  jennifer


out of interest, why are you sending an XML file from the client?

and what does jemplate have to do with it?

___
List: Catalyst@lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/