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

2008-05-15 Thread Zbigniew Lukasiak
Hi there,

This is a frequently recurring conversation - so I created a wiki page
to gather all the points where we reached some consensus:
http://catwiki.toeat.com/crud.  For the start I just dumped my
opinions.  I tried to be not controversial - but it is a wiki - if you
don't agree then you can edit it and make it more acceptable for you.

I am especially waiting for people with opinions on the REST and
browser REST part - I have got much knowledge in that area.

Cheers,
Zbigniew

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.

 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/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-15 Thread Zbigniew Lukasiak
On Thu, May 15, 2008 at 7:31 PM, Mark Trostler [EMAIL PROTECTED] wrote:
 You don't need 'create'  'update'  'delete' parts of your URL - those
 should be denoted by the request type - POST, PUT, or DELETE right?

Yes - you are right about REST, but what something more than that.  We
want to have is a REST interface together with something REST-like
that will work for browsers.

 Similarly you don't need 'id' in the url - so POST to /api/rest/cd will
 create a cd.  A PUT to /api/rest/cd/5 will update that CD - a DELETE to
 /api/rest/cd/5 will delete that CD...

Additionally we would like to have other non REST actions in the same
controller.  This mixing will require some separation between the
method names and the object id (which is data).  This is why I propose
/cd/instance/5 for the retrieve action.


--
Zbigniew

___
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-06 Thread Peter Karman


On 05/05/2008 02:33 PM, luke saunders wrote:
 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?
 

A few reasons.

One, the CRUD::REST primary design goal is to allow you to simply change your 
@ISA list in
order to switch from RPC to REST style URIs. If you are already using a
CX::CRUD::Controller-based class, you just put CX::CRUD::REST at the front of 
your @ISA
list and voila. That goal would have required a bit more method aliasing and 
other hackery
in order to support the *_VERB API in C::C::REST.

Two, the C::C::REST module (and related Action class) have a lot of support for 
automatic
serialization. CX::CRUD is completely agnostic about response type. Maybe it 
shouldn't be.
But it is.

Three, C::C::REST does not have real-world browser HTTP use in mind, as
REST::ForBrowsers does. That's not bad; it's just more pure imo. CX::CRUD 
tries to
support both, and as of yesterday, svn has support for the 'x-tunneled-method' 
param like
REST::ForBrowsers does.

Four, I didn't need the overhead. :)

Having said all that, I expect that C::C::REST could work well with 
CX::CRUD::REST, and
I'd love to see a patch that implements it, bearing in mind the points above.

-- 
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/


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

2008-05-05 Thread Matt S Trout
On Sun, May 04, 2008 at 09:06:30AM -0700, J. Shirley wrote:
 On Sun, May 4, 2008 at 8:52 AM, Zbigniew Lukasiak [EMAIL PROTECTED] wrote:
 
   Sorry but I don't understand your point - so maybe first I'll restate
   mine.  If you have primary key in the database that is of type varchar
   (or char or ...) then 'create' is a legitimage value for that primary
   key.
 
   If you just don't like the string 'id' in the URI - then I have not
   any preference to that - it can be /foo/primary_key/ for me.
 
 
 My point is that you do not have to use the primary key as the record
 lookup identifier.
 
 A user has no control over the record lookup identifier (ID) when you
 do things like /user/{primary_key} (or /user/id/{primary_key}, which
 is just converting named params to positional in a weird way).  In a
 lot of cases, the record lookup identifier makes more sense to be
 somewhat bound to the user.  As an example, lets say registering for a
 web service where you have to have a unique login:
 POST /user/jshirley
 ---
 login: jshirley
 first_name: Jay
 last_name: Shirley
 ...
 
 Now, it's a simple check here - does /user/jshirley exist?  If so,
 reject the request appropriately.  If not, create the user at
 /user/jshirley.
 
 The primary key that the database uses is completely useless to the
 user.  /user/1634254 is silly, /user/jshirley is meaningful.

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.

-- 
  Matt S Trout   Need help with your Catalyst or DBIx::Class project?
   Technical Directorhttp://www.shadowcat.co.uk/catalyst/
 Shadowcat Systems Ltd.  Want a managed development or deployment platform?
http://chainsawblues.vox.com/http://www.shadowcat.co.uk/servers/

___
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 J. Shirley
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:
   On Sun, May 4, 2008 at 8:52 AM, Zbigniew Lukasiak [EMAIL PROTECTED] 
 wrote:
   
 Sorry but I don't understand your point - so maybe first I'll restate
 mine.  If you have primary key in the database that is of type varchar
 (or char or ...) then 'create' is a legitimage value for that primary
 key.
   
 If you just don't like the string 'id' in the URI - then I have not
 any preference to that - it can be /foo/primary_key/ for me.
   
  
   My point is that you do not have to use the primary key as the record
   lookup identifier.
  
   A user has no control over the record lookup identifier (ID) when you
   do things like /user/{primary_key} (or /user/id/{primary_key}, which
   is just converting named params to positional in a weird way).  In a
   lot of cases, the record lookup identifier makes more sense to be
   somewhat bound to the user.  As an example, lets say registering for a
   web service where you have to have a unique login:
   POST /user/jshirley
   ---
   login: jshirley
   first_name: Jay
   last_name: Shirley
   ...
  
   Now, it's a simple check here - does /user/jshirley exist?  If so,
   reject the request appropriately.  If not, create the user at
   /user/jshirley.
  
   The primary key that the database uses is completely useless to the
   user.  /user/1634254 is silly, /user/jshirley is meaningful.

  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.

If we were talking about RPC, that would be a differently titled
thread and different arguments.

___
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 J. Shirley
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,
and the /foo/id/{id} is nothing more than a conversion from named
parameters to positional, and ugly.

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.

___
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 Zbigniew Lukasiak
On Mon, May 5, 2008 at 6: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,
  and the /foo/id/{id} is nothing more than a conversion from named
  parameters to positional, and ugly.

  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.

The point is about having something that will work as REST for
automated agents and also work for browsers by some emulation or what
ever - so you'll have some additional actions on the controller as
well.  Additionally if we really want to make this REST Role (assuming
Moose Catalyst by that time) - then the user of the library can have
his own actions.  In both way you'll have a clash if we go your way.

Because /foo/id/{id} looks like a parameter - which is the only
argument agains it and is just a bit of pedantry on your side - you
would allow for broken logic?


-- 
Zbigniew Lukasiak
http://brudnopis.blogspot.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/


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 Matt S Trout
On Mon, May 05, 2008 at 07:50:08AM -0700, 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:
On Sun, May 4, 2008 at 8:52 AM, Zbigniew Lukasiak [EMAIL PROTECTED] 
  wrote:

  Sorry but I don't understand your point - so maybe first I'll restate
  mine.  If you have primary key in the database that is of type varchar
  (or char or ...) then 'create' is a legitimage value for that primary
  key.

  If you just don't like the string 'id' in the URI - then I have not
  any preference to that - it can be /foo/primary_key/ for me.

   
My point is that you do not have to use the primary key as the record
lookup identifier.
   
A user has no control over the record lookup identifier (ID) when you
do things like /user/{primary_key} (or /user/id/{primary_key}, which
is just converting named params to positional in a weird way).  In a
lot of cases, the record lookup identifier makes more sense to be
somewhat bound to the user.  As an example, lets say registering for a
web service where you have to have a unique login:
POST /user/jshirley
---
login: jshirley
first_name: Jay
last_name: Shirley
...
   
Now, it's a simple check here - does /user/jshirley exist?  If so,
reject the request appropriately.  If not, create the user at
/user/jshirley.
   
The primary key that the database uses is completely useless to the
user.  /user/1634254 is silly, /user/jshirley is meaningful.
 
   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.

You'd never have a /user/recent or similar URL? I guess if you assume that
all views onto the collection are done via query parameters, or just
move that funcationality to /recent-users or similar then it doesn't matter.

But that's a different sort of uglification of the URL; it doesn't get rid
of it.

And it still doesn't help if you want to allow lookup by more than one
name so far as I can see.

-- 
  Matt S Trout   Need help with your Catalyst or DBIx::Class project?
   Technical Directorhttp://www.shadowcat.co.uk/catalyst/
 Shadowcat Systems Ltd.  Want a managed development or deployment platform?
http://chainsawblues.vox.com/http://www.shadowcat.co.uk/servers/

___
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 J. Shirley
On Mon, May 5, 2008 at 9:49 AM, Zbigniew Lukasiak [EMAIL PROTECTED] wrote:

 On Mon, May 5, 2008 at 6: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,
and the /foo/id/{id} is nothing more than a conversion from named
parameters to positional, and ugly.
  
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.

  The point is about having something that will work as REST for
  automated agents and also work for browsers by some emulation or what
  ever - so you'll have some additional actions on the controller as
  well.  Additionally if we really want to make this REST Role (assuming
  Moose Catalyst by that time) - then the user of the library can have
  his own actions.  In both way you'll have a clash if we go your way.

  Because /foo/id/{id} looks like a parameter - which is the only
  argument agains it and is just a bit of pedantry on your side - you
  would allow for broken logic?


That's just one argument that is most obvious.  The other argument is
that it adds additional entry points into an entity that you have to
keep in sync.

If you have /foo/id/{id} and /foo/name/{name} that are two paths to
the same entity, but {name} is not immutable you have broken
navigation at some point (bookmarks, etc).  So you have two immutable
entities for the same thing?  I fail to see why that works.  Which
leads into my main argument that using the primary key as the record
lookup identifier (in many cases) is simply bad design.

This strategy is redundancy of the oddest form to me, and it yields
more complications down the road as applications become more complex.

If you remove the redundancy, and each object has a well-defined
identifier, a POST to /foo will create a new entity which redirects to
/foo/{identifier}.  It's easy to duplicate functionality that a POST
to /foo/{identifier} works the same as a POST to just /foo, and can
generate $identifier.  I fail to see why a /create action needs to
exist in the first place on /foo.

Now, for browser-compatibility methods it isn't a bad thing having
/foo/{identifier}/(edit|delete).  The business with /foo/id/{ident}
there so that you don't conflict with a /create action on /foo is
just silly, and a sign of inadequate forethought into your resource
structure.  But again, this has very little to do with REST and more
to do with a sane URI structure (although not having an explicit
/create action is more on the RESTful side, I never have encountered
an issue having POST /foo handle item creation).

So, yes, it is pedantic but I don't view it as broken logic.  I view
it as tidy logic that doesn't employ the use of URI hacks to get
around browser deficiencies.

-J

___
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 J. Shirley
On Mon, May 5, 2008 at 10:02 AM, Matt S Trout [EMAIL PROTECTED] wrote:

 On Mon, May 05, 2008 at 07:50:08AM -0700, 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:
  On Sun, May 4, 2008 at 8:52 AM, Zbigniew Lukasiak [EMAIL PROTECTED] 
 wrote:
  
Sorry but I don't understand your point - so maybe first I'll 
 restate
mine.  If you have primary key in the database that is of type 
 varchar
(or char or ...) then 'create' is a legitimage value for that 
 primary
key.
  
If you just don't like the string 'id' in the URI - then I have not
any preference to that - it can be /foo/primary_key/ for me.
  
 
  My point is that you do not have to use the primary key as the record
  lookup identifier.
 
  A user has no control over the record lookup identifier (ID) when you
  do things like /user/{primary_key} (or /user/id/{primary_key}, which
  is just converting named params to positional in a weird way).  In a
  lot of cases, the record lookup identifier makes more sense to be
  somewhat bound to the user.  As an example, lets say registering for a
  web service where you have to have a unique login:
  POST /user/jshirley
  ---
  login: jshirley
  first_name: Jay
  last_name: Shirley
  ...
 
  Now, it's a simple check here - does /user/jshirley exist?  If so,
  reject the request appropriately.  If not, create the user at
  /user/jshirley.
 
  The primary key that the database uses is completely useless to the
  user.  /user/1634254 is silly, /user/jshirley is meaningful.
   
 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.

  You'd never have a /user/recent or similar URL? I guess if you assume that
  all views onto the collection are done via query parameters, or just
  move that funcationality to /recent-users or similar then it doesn't matter.

  But that's a different sort of uglification of the URL; it doesn't get rid
  of it.

  And it still doesn't help if you want to allow lookup by more than one
  name so far as I can see.



Search vs. Browse is separate user actions and deserves separate resource space.

/user implies a single user.
/users implies browsing.

So in this hypothetical case I would probably have a top level
namespace for /browse that had its own hierarchy (since most people
are going to browse more than just people)
/browse/users/recent

But... I also would do /browse/people/recent

Now you have a better (read-only) browse namespace on your site and it
descends into a hierarchy appropriately.

___
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 J. Shirley
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 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/


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

2008-05-05 Thread Peter Karman


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

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/


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

2008-05-05 Thread J. Shirley
On Mon, May 5, 2008 at 11:28 AM, 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

  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/



karpet++

___
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 J. Shirley
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'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.

  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 my URLs out in a definitive hierarchy.  If people want
an implicit create action, a /foo/-/create looks better to me than
having /foo/create, because I have the level of /foo to be the plural,
/foo/{id} to be the singular (in a simple CRUD example).
/foo/-/create is fine, because you can have a rule that - is never
an acceptable record identifier.

All of this stuff is mostly just standardizing on a set of 

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

2008-05-05 Thread Peter Karman


On 05/05/2008 03:29 PM, J. Shirley wrote:

 
 My vote is hierarchy like:
  /foo
/{token}   # Can be pk1 if you so desire
/- # - is never acceptable as an identifier
   /create # if you want an empty action here
 
 Now, I do vote against having an explicit create action, since POST
 /foo (or POST /foo/{token}) seems to be a more reasonable create
 action.

fwiw, CX::CRUD::REST uses:

http://search.cpan.org/~karman/CatalystX-CRUD-0.25/lib/CatalystX/CRUD/REST.pm#SYNOPSIS

I use 0 (zero) as my reserved PK value since seq PKs start at 1 and zero 
evaluates as
false in Perl.

 my ($self, $c, $oid) = @_;
 if (!$oid) {
   # could be absent or zero, either is fine
   # ...
 }

Also, I adopted drolsky's suggestion of /create_form instead of /create in 
order to keep
the RESTful no-verb style URIs.

-- 
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/


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: 

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

2008-05-04 Thread J. Shirley
On Sun, May 4, 2008 at 1:52 AM, Zbigniew Lukasiak [EMAIL PROTECTED] wrote:
 On Sun, May 4, 2008 at 7:05 AM, J. Shirley [EMAIL PROTECTED] wrote:
  On a side note about REST - REST doesn't mean human readable URLs.  It
means representative URLs.  The bit about cd/id/{CDID}/ smells like
named parameters going into positional parameters.  What is the real
difference between cd?id={CDID}action=delete, aside from different
characters?  Where as with REST, /cd/{id} is a unique identifier for
that object and hence a full representation.

  The problem I see with /cd/{id} is that when you have a primary key
  that is 'create' - this would clash with the 'create' action.
  /cd/id/{id} let's you separate the reserved words from the user data.



A pet peeve of mine is that people seem to have this weird idea that
primary key == id.  An id can just be some human readable mechanism to
looking up the item, where as the primary key is what is actually used
by the database to determine the relations.

They do not have to be the same field but often times they are out of
convenience.  In cases like this, they simply shouldn't be though.

___
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-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/


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

2008-05-04 Thread J. Shirley
On Sun, May 4, 2008 at 8:52 AM, Zbigniew Lukasiak [EMAIL PROTECTED] wrote:

  Sorry but I don't understand your point - so maybe first I'll restate
  mine.  If you have primary key in the database that is of type varchar
  (or char or ...) then 'create' is a legitimage value for that primary
  key.

  If you just don't like the string 'id' in the URI - then I have not
  any preference to that - it can be /foo/primary_key/ for me.


My point is that you do not have to use the primary key as the record
lookup identifier.

A user has no control over the record lookup identifier (ID) when you
do things like /user/{primary_key} (or /user/id/{primary_key}, which
is just converting named params to positional in a weird way).  In a
lot of cases, the record lookup identifier makes more sense to be
somewhat bound to the user.  As an example, lets say registering for a
web service where you have to have a unique login:
POST /user/jshirley
---
login: jshirley
first_name: Jay
last_name: Shirley
...

Now, it's a simple check here - does /user/jshirley exist?  If so,
reject the request appropriately.  If not, create the user at
/user/jshirley.

The primary key that the database uses is completely useless to the
user.  /user/1634254 is silly, /user/jshirley is meaningful.

If the ID is generated, that gets a bit trickier but I usually handle
that with a POST to /user with the data and then let the application
forward me to the final URL of where the resource exists.

The other reason is that this system breaks when you no longer have
records tied to a database.  As an example, if you use an md5 sum of a
file as the identifier.  /file/1234 doesn't work because it isn't in a
database under that system (think of a MogileFS cluster or something
with hash keys rather than primary keys in the conventional sense) -
instead /file/{md5sum} is used.

In brief summary, over-utilization of primary keys as record lookup
identifiers ends up diminishing the human readability and
accessibility of your web service.   I'm not trying to win over any
converts, because I think there is a time and a place for each (even
in the same application, it just depends upon what each action is
really doing).  If I'm not building something that is REST/webservice
driven I tend to do the /user/{id or token} (with a simple regex to
check, and if someone has a login of all numbers then screw 'em) - but
it's a very different strategy when I work with webservices -- each
time I always make sure if the record lookup indicator should be the
primary key, and what cases should it not and then react accordingly.

___
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-04 Thread Christopher Laco

Zbigniew Lukasiak wrote:

On Sun, May 4, 2008 at 3:54 PM, J. Shirley [EMAIL PROTECTED] wrote:

On Sun, May 4, 2008 at 1:52 AM, Zbigniew Lukasiak [EMAIL PROTECTED] wrote:
  On Sun, May 4, 2008 at 7:05 AM, J. Shirley [EMAIL PROTECTED] wrote:


 On a side note about REST - REST doesn't mean human readable URLs.  It

 means representative URLs.  The bit about cd/id/{CDID}/ smells like
 named parameters going into positional parameters.  What is the real
 difference between cd?id={CDID}action=delete, aside from different
 characters?  Where as with REST, /cd/{id} is a unique identifier for
 that object and hence a full representation.
 
   The problem I see with /cd/{id} is that when you have a primary key
   that is 'create' - this would clash with the 'create' action.
   /cd/id/{id} let's you separate the reserved words from the user data.
 
 

 A pet peeve of mine is that people seem to have this weird idea that
 primary key == id.  An id can just be some human readable mechanism to
 looking up the item, where as the primary key is what is actually used
 by the database to determine the relations.

 They do not have to be the same field but often times they are out of
 convenience.  In cases like this, they simply shouldn't be though.


Sorry but I don't understand your point - so maybe first I'll restate
mine.  If you have primary key in the database that is of type varchar
(or char or ...) then 'create' is a legitimage value for that primary
key.

If you just don't like the string 'id' in the URI - then I have not
any preference to that - it can be /foo/primary_key/ for me.



My pet peeve is that /foo/primary_key makes computers happy... but not 
people.



/products/23
/products/ABC-1234


The first is the PK for a product record..
The second is the actual sku for a product... just a unique as the 
pk...but not the PK itself...



Now what does id mean in this case?
What id your SKU is a numeric just like your PK?

Two different and equally useful ways to get at the same resource.

If you're talking about an interface where humans know the skus, and 
computers know the id (restfully and/or remotely).. you need a sane uri:


/products/id/id
/products/sku/sku

In the end, I always run into a situation where humans (think marketing 
SEO pushers who know not of REST) want something other than a true 
restful uri.


-=Chris

___
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-04 Thread Steve Atkins


On May 4, 2008, at 9:02 AM, Christopher Laco wrote:




My pet peeve is that /foo/primary_key makes computers happy... but  
not people.



/products/23
/products/ABC-1234


The first is the PK for a product record..
The second is the actual sku for a product... just a unique as the  
pk...but not the PK itself...



Now what does id mean in this case?
What id your SKU is a numeric just like your PK?

Two different and equally useful ways to get at the same resource.

If you're talking about an interface where humans know the skus, and  
computers know the id (restfully and/or remotely).. you need a sane  
uri:


/products/id/id
/products/sku/sku

In the end, I always run into a situation where humans (think  
marketing SEO pushers who know not of REST) want something other  
than a true restful uri.


Part of the problem here might be the wish to avoid a natural
primary key in the database schema, preferring a synthetic
primary key even when there's a perfectly good natural
primary key.

That's something that I expect to see from the ruby on
rails crowd, not the (presumably more pragmatic) perl folks.

If your SKU is unique, then it's a perfectly good primary
key, and having a synthetic numeric primary key isn't
necessary. (It might be the right choice in some cases,
and not in others, but the primary key is an arbitrary
integer is not a given).

Cheers,
  Steve



___
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-04 Thread Zbigniew Lukasiak
On Sun, May 4, 2008 at 6:06 PM, J. Shirley [EMAIL PROTECTED] wrote:
 On Sun, May 4, 2008 at 8:52 AM, Zbigniew Lukasiak [EMAIL PROTECTED] wrote:
  

   Sorry but I don't understand your point - so maybe first I'll restate
mine.  If you have primary key in the database that is of type varchar
(or char or ...) then 'create' is a legitimage value for that primary
key.
  
If you just don't like the string 'id' in the URI - then I have not
any preference to that - it can be /foo/primary_key/ for me.
  

  My point is that you do not have to use the primary key as the record
  lookup identifier.

  A user has no control over the record lookup identifier (ID) when you
  do things like /user/{primary_key} (or /user/id/{primary_key}, which
  is just converting named params to positional in a weird way).  In a
  lot of cases, the record lookup identifier makes more sense to be
  somewhat bound to the user.  As an example, lets say registering for a
  web service where you have to have a unique login:
 POST /user/jshirley
 ---
 login: jshirley
 first_name: Jay
 last_name: Shirley
 ...

  Now, it's a simple check here - does /user/jshirley exist?  If so,
  reject the request appropriately.  If not, create the user at
  /user/jshirley.

  The primary key that the database uses is completely useless to the
  user.  /user/1634254 is silly, /user/jshirley is meaningful.

  If the ID is generated, that gets a bit trickier but I usually handle
  that with a POST to /user with the data and then let the application
  forward me to the final URL of where the resource exists.

  The other reason is that this system breaks when you no longer have
  records tied to a database.  As an example, if you use an md5 sum of a
  file as the identifier.  /file/1234 doesn't work because it isn't in a
  database under that system (think of a MogileFS cluster or something
  with hash keys rather than primary keys in the conventional sense) -
  instead /file/{md5sum} is used.

  In brief summary, over-utilization of primary keys as record lookup
  identifiers ends up diminishing the human readability and
  accessibility of your web service.   I'm not trying to win over any
  converts, because I think there is a time and a place for each (even
  in the same application, it just depends upon what each action is
  really doing).  If I'm not building something that is REST/webservice
  driven I tend to do the /user/{id or token} (with a simple regex to
  check, and if someone has a login of all numbers then screw 'em) - but
  it's a very different strategy when I work with webservices -- each
  time I always make sure if the record lookup indicator should be the
  primary key, and what cases should it not and then react accordingly.

Then we are talking about two diffrent things.  My point is that you
should not have /foo/create and foo/{id or token} - because you mix a
reserverd work 'create' with data, you can never guarantee that the
data, be it primary key or token or whatever, does not contain
'create'.

I do understand that in full REST design you would not have a
'/foo/create/' uri - but if you want to add this REST as an add-on to
a controller you'll still have other methods on the controller that
could conflict with the token/id.

-- 
Zbigniew Lukasiak
http://brudnopis.blogspot.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/