Login | Register For Free | Help
Search for: (Advanced)

Mailing List Archive: Catalyst: Users

RFC: Catalyst::Controller::REST::DBIC

 

 

First page Previous page 1 2 3 Next page Last page  View All Catalyst users RSS feed   Index | Next | Previous | View Threaded


luke.saunders at gmail

May 3, 2008, 5:38 PM

Post #1 of 63 (472 views)
Permalink
RFC: Catalyst::Controller::REST::DBIC

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.000000.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[at]lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst[at]lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/


pat at patspam

May 3, 2008, 9:29 PM

Post #2 of 63 (451 views)
Permalink
Re: RFC: Catalyst::Controller::REST::DBIC [In reply to]

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


Those URLs don't strike me as very RESTful.

Patrick


jshirley at gmail

May 3, 2008, 10:05 PM

Post #3 of 63 (451 views)
Permalink
Re: RFC: Catalyst::Controller::REST::DBIC [In reply to]

On Sat, May 3, 2008 at 9:29 PM, Patrick Donelan <pat[at]patspam.com> wrote:
>
> > 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]
>
> Those URLs don't strike me as very RESTful.
>
> Patrick
>

That is my first impression. My work is an enhancement from
Catalyst::Action::REST, which is a great module already out on CPAN
and used by other people (holoway++).

I'm all for collaboration, but my work is mostly tied to have exposed
webservices (in addition to a web-browser compatibility layer) via
REST. By that I mean that I expect, and require, that I can do a PUT
/api/rest/cd/[cdid], DELETE /api/rest/cd/[CDID]

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.

I understand the limitations of /cd/id/{id} vs. /cd/name/{id}, but a
lookup and redirection service is a better solution that polluting
your absolute unique representative URL spaces.

You can catch me on IRC next week, as I'm actively working on this for
$work and it's getting real dev time (finally). My work is
functionally complete, but lacking test cases; it is just a refactor
of existing code in production.

-J

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


pagaltzis at gmx

May 4, 2008, 12:10 AM

Post #4 of 63 (446 views)
Permalink
Re: RFC: Catalyst::Controller::REST::DBIC [In reply to]

* luke saunders <luke.saunders[at]gmail.com> [2008-05-04 02:50]:
> Also it doesn't distinguish between POST, PUT, DELETE and GET
> HTTP requests favouring instead entirely separate endpoints,
> but that's up for discussion.

Putting the verb in the URI is RPC, not REST. This is not a
matter of discussion.

Regards,
--
Aristotle Pagaltzis // <http://plasmasturm.org/>

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


zzbbyy at gmail

May 4, 2008, 1:52 AM

Post #5 of 63 (446 views)
Permalink
Re: RFC: Catalyst::Controller::REST::DBIC [In reply to]

On Sun, May 4, 2008 at 7:05 AM, J. Shirley <jshirley[at]gmail.com> wrote:
>
> On Sat, May 3, 2008 at 9:29 PM, Patrick Donelan <pat[at]patspam.com> wrote:
> >
> > > 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]
> >
> > Those URLs don't strike me as very RESTful.
> >
> > Patrick
> >
>
> That is my first impression. My work is an enhancement from
> Catalyst::Action::REST, which is a great module already out on CPAN
> and used by other people (holoway++).
>
> I'm all for collaboration, but my work is mostly tied to have exposed
> webservices (in addition to a web-browser compatibility layer) via
> REST. By that I mean that I expect, and require, that I can do a PUT
> /api/rest/cd/[cdid], DELETE /api/rest/cd/[CDID]
>
> 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.


>
> I understand the limitations of /cd/id/{id} vs. /cd/name/{id}, but a
> lookup and redirection service is a better solution that polluting
> your absolute unique representative URL spaces.
>
> You can catch me on IRC next week, as I'm actively working on this for
> $work and it's getting real dev time (finally). My work is
> functionally complete, but lacking test cases; it is just a refactor
> of existing code in production.
>
> -J
>
>
>
> _______________________________________________
> List: Catalyst[at]lists.scsys.co.uk
> Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
> Searchable archive: http://www.mail-archive.com/catalyst[at]lists.scsys.co.uk/
> Dev site: http://dev.catalyst.perl.org/
>



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

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


zzbbyy at gmail

May 4, 2008, 2:20 AM

Post #6 of 63 (445 views)
Permalink
Re: RFC: Catalyst::Controller::REST::DBIC [In reply to]

On Sun, May 4, 2008 at 2:38 AM, luke saunders <luke.saunders[at]gmail.com> 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.000000.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.

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.

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[at]lists.scsys.co.uk
> Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
> Searchable archive: http://www.mail-archive.com/catalyst[at]lists.scsys.co.uk/
> Dev site: http://dev.catalyst.perl.org/
>



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

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


luke.saunders at gmail

May 4, 2008, 3:09 AM

Post #7 of 63 (446 views)
Permalink
Re: RFC: Catalyst::Controller::REST::DBIC [In reply to]

On Sun, May 4, 2008 at 6:05 AM, J. Shirley <jshirley[at]gmail.com> wrote:
>
> On Sat, May 3, 2008 at 9:29 PM, Patrick Donelan <pat[at]patspam.com> wrote:
> >
> > > 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]
> >
> > Those URLs don't strike me as very RESTful.
> >
> > Patrick
> >
>
> That is my first impression. My work is an enhancement from
> Catalyst::Action::REST, which is a great module already out on CPAN
> and used by other people (holoway++).
>
> I'm all for collaboration, but my work is mostly tied to have exposed
> webservices (in addition to a web-browser compatibility layer) via
> REST. By that I mean that I expect, and require, that I can do a PUT
> /api/rest/cd/[cdid], DELETE /api/rest/cd/[CDID]
>

Sure, but I have previously had problems getting a browser to send PUT
requests from JS so separate endpoints were required. In fact the Dojo
author even said that PUT was a nightmare, use POST (possibly fixed in
recent Dojo version / browsers). i see no reason why you can't have
one base action which forwards to the others based on request type so
that both URL types are exposed.

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

I find having the id in the path to be a clearer distinction between
object level operations and class level operations. It's the
difference between object and all objects.

> You can catch me on IRC next week, as I'm actively working on this for
> $work and it's getting real dev time (finally). My work is
> functionally complete, but lacking test cases; it is just a refactor
> of existing code in production.
>

So you don't want to automate any actual operations? In which case if
anything my module could subclass yours.

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


luke.saunders at gmail

May 4, 2008, 3:23 AM

Post #8 of 63 (445 views)
Permalink
Re: RFC: Catalyst::Controller::REST::DBIC [In reply to]

On Sun, May 4, 2008 at 10:20 AM, Zbigniew Lukasiak <zzbbyy[at]gmail.com> wrote:
>
> On Sun, May 4, 2008 at 2:38 AM, luke saunders <luke.saunders[at]gmail.com> 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.000000.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[at]lists.scsys.co.uk
> > Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
> > Searchable archive: http://www.mail-archive.com/catalyst[at]lists.scsys.co.uk/
> > Dev site: http://dev.catalyst.perl.org/
> >
>
>
>
> --
> Zbigniew Lukasiak
> http://brudnopis.blogspot.com/
>
> _______________________________________________
> List: Catalyst[at]lists.scsys.co.uk
> Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
> Searchable archive: http://www.mail-archive.com/catalyst[at]lists.scsys.co.uk/
> Dev site: http://dev.catalyst.perl.org/
>

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


zzbbyy at gmail

May 4, 2008, 3:58 AM

Post #9 of 63 (445 views)
Permalink
Re: RFC: Catalyst::Controller::REST::DBIC [In reply to]

On Sun, May 4, 2008 at 12:23 PM, luke saunders <luke.saunders[at]gmail.com> wrote:
>
> On Sun, May 4, 2008 at 10:20 AM, Zbigniew Lukasiak <zzbbyy[at]gmail.com> wrote:
> >
> > On Sun, May 4, 2008 at 2:38 AM, luke saunders <luke.saunders[at]gmail.com> 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.000000.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.

I think we can still make it compatible, if we agree on some kind of
internal API.

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

It is I think quite common convention to use '.' dot for that:

param1.some_relation.field_value

or

some_param.some_multi_relation.1.field_value

>
>
> > 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[at]lists.scsys.co.uk
> > > Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
> > > Searchable archive: http://www.mail-archive.com/catalyst[at]lists.scsys.co.uk/
> > > Dev site: http://dev.catalyst.perl.org/
> > >
> >
> >
> >
> > --
> > Zbigniew Lukasiak
> > http://brudnopis.blogspot.com/
> >
> > _______________________________________________
> > List: Catalyst[at]lists.scsys.co.uk
> > Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
> > Searchable archive: http://www.mail-archive.com/catalyst[at]lists.scsys.co.uk/
> > Dev site: http://dev.catalyst.perl.org/
> >
>
> _______________________________________________
> List: Catalyst[at]lists.scsys.co.uk
> Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
> Searchable archive: http://www.mail-archive.com/catalyst[at]lists.scsys.co.uk/
> Dev site: http://dev.catalyst.perl.org/
>



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

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


luke.saunders at gmail

May 4, 2008, 4:28 AM

Post #10 of 63 (446 views)
Permalink
Re: RFC: Catalyst::Controller::REST::DBIC [In reply to]

On Sun, May 4, 2008 at 11:58 AM, Zbigniew Lukasiak <zzbbyy[at]gmail.com> wrote:
>
> On Sun, May 4, 2008 at 12:23 PM, luke saunders <luke.saunders[at]gmail.com> wrote:
> >
> > On Sun, May 4, 2008 at 10:20 AM, Zbigniew Lukasiak <zzbbyy[at]gmail.com> wrote:
> > >
> > > On Sun, May 4, 2008 at 2:38 AM, luke saunders <luke.saunders[at]gmail.com> 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.000000.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.
>
> I think we can still make it compatible, if we agree on some kind of
> internal API.
>

As in make this module compatible with your new module? Perhaps as a
base class without form generation?

> > > 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?
> >
>
> It is I think quite common convention to use '.' dot for that:
>
> param1.some_relation.field_value
>
> or
>
> some_param.some_multi_relation.1.field_value
>

Makes sense. I prefer that to the add_to_rel action, especially if
this is to remain a REST module rather than an RPC module.

The piece of functionality I always wanted but didn't see a clean
solution to was specifying complex conditions to the 'list' action,
for example only CDs which have a track called 'Badgers', which
requires specifying a join and a related condition. I wonder if it
makes sense to represent that this way too.

>
>
> >
> >
> > > 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[at]lists.scsys.co.uk
> > > > Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
> > > > Searchable archive: http://www.mail-archive.com/catalyst[at]lists.scsys.co.uk/
> > > > Dev site: http://dev.catalyst.perl.org/
> > > >
> > >
> > >
> > >
> > > --
> > > Zbigniew Lukasiak
> > > http://brudnopis.blogspot.com/
> > >
> > > _______________________________________________
> > > List: Catalyst[at]lists.scsys.co.uk
> > > Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
> > > Searchable archive: http://www.mail-archive.com/catalyst[at]lists.scsys.co.uk/
> > > Dev site: http://dev.catalyst.perl.org/
> > >
> >
> > _______________________________________________
> > List: Catalyst[at]lists.scsys.co.uk
> > Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
> > Searchable archive: http://www.mail-archive.com/catalyst[at]lists.scsys.co.uk/
> > Dev site: http://dev.catalyst.perl.org/
> >
>
>
>
> --
> Zbigniew Lukasiak
> http://brudnopis.blogspot.com/
>
> _______________________________________________
> List: Catalyst[at]lists.scsys.co.uk
> Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
> Searchable archive: http://www.mail-archive.com/catalyst[at]lists.scsys.co.uk/
> Dev site: http://dev.catalyst.perl.org/
>

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


zzbbyy at gmail

May 4, 2008, 6:12 AM

Post #11 of 63 (445 views)
Permalink
Re: RFC: Catalyst::Controller::REST::DBIC [In reply to]

On Sun, May 4, 2008 at 1:28 PM, luke saunders <luke.saunders[at]gmail.com> wrote:
> >
> > I think we can still make it compatible, if we agree on some kind of
> > internal API.
> >
>
> As in make this module compatible with your new module? Perhaps as a
> base class without form generation?

Yes - I am thinking about something where you have a separate methods
for validating the parameters and updating/creating the object in the
database - so that I could override them in my sub-class.

> >
> > It is I think quite common convention to use '.' dot for that:
> >
> > param1.some_relation.field_value
> >
> > or
> >
> > some_param.some_multi_relation.1.field_value
> >
>
> Makes sense. I prefer that to the add_to_rel action, especially if
> this is to remain a REST module rather than an RPC module.
>

It does not bother me if you leave those actions.

> The piece of functionality I always wanted but didn't see a clean
> solution to was specifying complex conditions to the 'list' action,
> for example only CDs which have a track called 'Badgers', which
> requires specifying a join and a related condition. I wonder if it
> makes sense to represent that this way too.
>

Well - this is in my plans as well - as search in InstantCRUD :) I am
thinking to base it on the technique I described in my Advent article:
http://catalyst.perl.org/calendar/2007/16

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

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


jon at jrock

May 4, 2008, 6:18 AM

Post #12 of 63 (445 views)
Permalink
Re: RFC: Catalyst::Controller::REST::DBIC [In reply to]

* 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.

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

Regards,
Jonathan Rockway

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

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


jshirley at gmail

May 4, 2008, 6:54 AM

Post #13 of 63 (444 views)
Permalink
Re: RFC: Catalyst::Controller::REST::DBIC [In reply to]

On Sun, May 4, 2008 at 1:52 AM, Zbigniew Lukasiak <zzbbyy[at]gmail.com> wrote:
> On Sun, May 4, 2008 at 7:05 AM, J. Shirley <jshirley[at]gmail.com> 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[at]lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst[at]lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/


luke.saunders at gmail

May 4, 2008, 6:58 AM

Post #14 of 63 (445 views)
Permalink
Re: RFC: Catalyst::Controller::REST::DBIC [In reply to]

On Sun, May 4, 2008 at 2:18 PM, Jonathan Rockway <jon[at]jrock.us> 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[at]lists.scsys.co.uk
> Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
> Searchable archive: http://www.mail-archive.com/catalyst[at]lists.scsys.co.uk/
> Dev site: http://dev.catalyst.perl.org/
>

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


dbix-class at trout

May 4, 2008, 7:15 AM

Post #15 of 63 (443 views)
Permalink
Re: Re: RFC: Catalyst::Controller::REST::DBIC [In reply to]

On Sun, May 04, 2008 at 09:10:56AM +0200, Aristotle Pagaltzis wrote:
> * luke saunders <luke.saunders[at]gmail.com> [2008-05-04 02:50]:
> > Also it doesn't distinguish between POST, PUT, DELETE and GET
> > HTTP requests favouring instead entirely separate endpoints,
> > but that's up for discussion.
>
> Putting the verb in the URI is RPC, not REST. This is not a
> matter of discussion.

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.

Or at least a matter for determining an architecture that allows you to
use whatever alternative you like.

Please don't let your obsessive REST advocacy blind you to pragmatic
software development issues; it's starting to get boring.

--
Matt S Trout Need help with your Catalyst or DBIx::Class project?
Technical Director http://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[at]lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst[at]lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/


jshirley at gmail

May 4, 2008, 7:58 AM

Post #16 of 63 (445 views)
Permalink
Re: Re: RFC: Catalyst::Controller::REST::DBIC [In reply to]

On Sun, May 4, 2008 at 7:15 AM, Matt S Trout <dbix-class[at]trout.me.uk> wrote:
> On Sun, May 04, 2008 at 09:10:56AM +0200, Aristotle Pagaltzis wrote:
> > * luke saunders <luke.saunders[at]gmail.com> [2008-05-04 02:50]:
> > > Also it doesn't distinguish between POST, PUT, DELETE and GET
> > > HTTP requests favouring instead entirely separate endpoints,
> > > but that's up for discussion.
> >
> > Putting the verb in the URI is RPC, not REST. This is not a
> > matter of discussion.
>
> 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.
>
> Or at least a matter for determining an architecture that allows you to
> use whatever alternative you like.
>
> Please don't let your obsessive REST advocacy blind you to pragmatic
> software development issues; it's starting to get boring.
>

Naming things REST when they aren't confuses the namespace and further
propagates the confusion about what REST actually is. Call it
something else and do everybody who actually tries to build RESTful
apps a favor. Trying to argue in favor of naming something that isn't
REST in any way REST does a disservice to the world. And kills
puppies, deprives worthy little girls of ponies, elects
neoconservatives to office and, quite possibly, lights a bag of
excrement on your porch then ringing your doorbell and running.

And, on a more topical note, my method for having actual REST and then
a dumbed down browser version is similar to jrockway's suggestion
about dispatch methods. My approach is a set of very thin actions
that exist outside of the main API space (or, what I've been playing
around with is a more adaptive interface based on what Dave Rolsky is
working on: http://search.cpan.org/~drolsky/Catalyst-Request-REST-ForBrowsers-0.01/lib/Catalyst/Request/REST/ForBrowsers.pm).
They really end up just being a sort of internal API to the base web
service. This also addresses the id == primary key issue, because in
your front-end browser-facing scheme, you have /book/id/{primary key},
which maps to /book/{unique identifier}.

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


zzbbyy at gmail

May 4, 2008, 8:52 AM

Post #17 of 63 (442 views)
Permalink
Re: RFC: Catalyst::Controller::REST::DBIC [In reply to]

On Sun, May 4, 2008 at 3:54 PM, J. Shirley <jshirley[at]gmail.com> wrote:
> On Sun, May 4, 2008 at 1:52 AM, Zbigniew Lukasiak <zzbbyy[at]gmail.com> wrote:
> > On Sun, May 4, 2008 at 7:05 AM, J. Shirley <jshirley[at]gmail.com> wrote:
>
> > > 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.

>
>
>
> _______________________________________________
> List: Catalyst[at]lists.scsys.co.uk
> Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
> Searchable archive: http://www.mail-archive.com/catalyst[at]lists.scsys.co.uk/
> Dev site: http://dev.catalyst.perl.org/
>



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

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


claco at chrislaco

May 4, 2008, 9:02 AM

Post #18 of 63 (442 views)
Permalink
Re: RFC: Catalyst::Controller::REST::DBIC [In reply to]

Zbigniew Lukasiak wrote:
> On Sun, May 4, 2008 at 3:54 PM, J. Shirley <jshirley[at]gmail.com> wrote:
>> On Sun, May 4, 2008 at 1:52 AM, Zbigniew Lukasiak <zzbbyy[at]gmail.com> wrote:
>> > On Sun, May 4, 2008 at 7:05 AM, J. Shirley <jshirley[at]gmail.com> wrote:
>>
>> > > 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[at]lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst[at]lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/


jshirley at gmail

May 4, 2008, 9:06 AM

Post #19 of 63 (442 views)
Permalink
Re: RFC: Catalyst::Controller::REST::DBIC [In reply to]

On Sun, May 4, 2008 at 8:52 AM, Zbigniew Lukasiak <zzbbyy[at]gmail.com> 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,