Re: [Catalyst] REST - like uri design for CRUD

2008-01-20 Thread Peter Karman



Zbigniew Lukasiak wrote on 1/20/08 1:56 PM:

I know this has been discussed already - but I can't find it in the archives.

What I conjured is:

/class/search
/class/id//view
/class/id//update
/class/create

Update and create use really the same logic and templates - so I just
forward to a create_or_update action from them.

What are your opinions?



that's essentially the CatalystX::CRUD::Controller API:

http://search.cpan.org/~karman/CatalystX-CRUD-0.22/lib/CatalystX/CRUD/Controller.pm

That API is intentionally RESTish, though there's no checking of HTTP method at 
all.

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

___
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] REST - like uri design for CRUD

2008-01-20 Thread Thomas L. Shinnick

At 01:56 PM 1/20/2008, Zbigniew Lukasiak wrote:

I know this has been discussed already - but I can't find it in the archives.

What I conjured is:

/class/search
/class/id//view
/class/id//update
/class/create

Update and create use really the same logic and templates - so I just
forward to a create_or_update action from them.

What are your opinions?

--
Zbigniew Lukasiak


spew register=pedant

The book RESTful Web Services has been very useful to me in 
understanding the confusion about what REST means when it comes to 
'verbs'.  And that I'm interested in how close one can come to 
'strict' REST design using Catalyst.


One important topic in the book is that people mix 'verbs' into their 
URIs when they shouldn't, or at least when they don't _have_ 
to.  Using the book's concepts your URIs would become


1)  GET/class?pattern=breadbox
2)  GET/class/id/
3)  PUT/class/id/
4)  POST /class

1) is your /class/search and says let me retrieve the 
representation/list of the items selected by searching for the given 
pattern, where the base URI would indicate the set/list of items, 
and the pattern is kept in the query parameters because it could be 
anything.  Note that the idea is that GET /class references the 
list of all items, and you here are just qualifying that search with 
the pattern.


2) Your /class/id//view would be seen in strict REST as just a 
GET of /class/id/.  The HTTP 'verb' GET already says give me a 
representation of the item.  Done.


3) Your /class/id//update would become a PUT of 
/class/id/, where the new representation coming from the remote 
client would _replace_ the old representation/data for that 
item.  This strict use of the HTTP 'PUT' verb is actually the hardest 
to accomplish, as it assumes that the remote client can receive and 
update a representation on the client, and then send it back using 
PUT.  It is easiest to picture this usage when the client completely 
replaces the old representation held on the server.  (see farther 
below for why)


4) Your /class/create becomes a POST to /class.  This was another 
concept brought out by the book.  The matter of who determines the 
item's 'id' is important.  Here we assume that the _server_ will 
determine the id of the new added item.  You do a POST to the base 
URI of the data area, and the server determines the new id, stores 
the data into the item, and does a redirect to tell the remote client 
where the new item is, that is, what is the new item's URI, for 
instance /class/id/1234.


Why is who determines the id important?  Because it says what HTTP 
verb you should use to create a new item.  If the server, you use 
POST to add another item.  (Much discussion of that most 
misunderstood of HTTP methods: POST in the book)  But if the remote 
client were to determine the id, say because the id is a license 
plate number input at the client, then strict REST would say the 
client should do a PUT to /class/id/STRWBYP and the client would 
send the complete data for the item.  The server would create the 
item using the id 'STRWBYP as requested by the client.


Creation using POST would say create a new item and tell me (the 
client) where you (the server) put it.  Creation using PUT defines 
where to put it to the server, because the client knows what the id should be.


So under some designs it is possible that PUT will be used for both 
creation of new items and update (replacement) of existing items.  In 
both these cases (under such a design) the client knows the correct 
id for the item.


Anyway this spew was prompted by the new pedant seeing 'REST' in the 
subject and then no mention of 'PUT', etc.  The book tries to be 
clear that it depends on both your design and the capabilities of 
the client whether you can implement using the strict REST HTTP 
verb set GET, PUT, and POST, or whether you must compromise on a 
REST-like set of GET and POST.  The authors discuss how to overload 
POST to effect PUT-like usage, because we have to implement in the 
real world.  But they are clear about the goals of RESTful design, 
the problems it solves, and the benefits it brings in the real world.


It looks to be very useful to consider URI design with a view towards 
how would I accomplish this by splitting my data objects into URI 
addressable data that can be manipulated using the full set of HTTP 
verbs GET, PUT, POST and HEAD.  (And not putting verbs into URIs that 
might be cached)


/spew ___
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] REST - like uri design for CRUD

2008-01-20 Thread Ashley

On Jan 20, 2008, at 1:33 PM, Thomas L. Shinnick wrote:

At 01:56 PM 1/20/2008, Zbigniew Lukasiak wrote:

/class/search
/class/id//view
/class/id//update
/class/create


spew register=pedant
One important topic in the book is that people mix 'verbs' into  
their URIs when they shouldn't, or at least when they don't _have_  
to.  Using the book's concepts your URIs would become


1)  GET/class?pattern=breadbox
2)  GET/class/id/
3)  PUT/class/id/
4)  POST /class
 /spew


Clipped a bunch. This is great food for thought. I am missing in this  
scheme how you would know to serve the form for updating. That seems  
to be the real point of /class/id//update. I suppose that should  
be /class/id//edit instead and it would, if it could, properly PUT  
the form to /class/id/, yes?


-Ashley

___
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] REST - like uri design for CRUD

2008-01-20 Thread Сергей Мартынов
  One important topic in the book is that people mix 'verbs' into their URIs
 when they shouldn't, or at least when they don't _have_ to.  Using the
 book's concepts your URIs would become

  1)  GET/class?pattern=breadbox
  2)  GET/class/id/
  3)  PUT/class/id/
  4)  POST /class

Nice clarification, thank you!

But is the /id/ part of url required? In most cases class would have
only one primary identifier, so we can shrink it to GET /class/ -
can't we?

And concerning case 3 - I think that rarely used PUT method could be
replaced with common POST to avoid possible problems with proxies,
etc.


-- 
С уважением, Сергей Мартынов.
___
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] REST - like uri design for CRUD

2008-01-20 Thread Christopher Laco

Dave Rolsky wrote:

On Sun, 20 Jan 2008, Thomas L. Shinnick wrote:

They specifically allow that when PUT is not available or 
impracticable (clients, firewalls, and proxies can get in the way), 
you could 'overload' POST by, for example, adding a query parameter 
_method=PUT to pass-thru the real request method.  The idea is that 
the handler would pick off this parameter and dispatch as though the 
HTTP method had really been PUT.  But you try to use this request like 
you would a 'real' PUT, in what the data contains and how it is used.


But this is a question I have, whether the REST dispatching modules 
have an capability like this, interpreting overloaded POSTs?


I added this to a custom Catalyst::Request subclass I use for my app. It 
looks like this:


 sub method
 {
 my $self = shift;

 return $self-NEXT::method(@_)
 if @_;

 return $self-{__method} if $self-{__method};

 my $method = $self-NEXT::method();

 return $method unless $method  uc $method eq 'POST';

 my $tunneled = $self-param('x-tunneled-method');

 return $self-{__method} = $tunneled ? $tunneled : $method;
 }


-dave


Here's my hack against my REST controller subclass of C::Controller::REST:


if ($c-request-method eq 'POST'  $c-request-param('_method')) {
$c-request-method(uc $c-request-param('_method'));
};



Since the REST package already has a Request subclass, I didn't really 
want to make yet another one...esp if the SOAP stuff also gets loaded.


-=Chris



signature.asc
Description: OpenPGP digital signature
___
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] REST - like uri design for CRUD

2008-01-20 Thread Dave Rolsky

On Sun, 20 Jan 2008, Thomas L. Shinnick wrote:

They specifically allow that when PUT is not available or impracticable 
(clients, firewalls, and proxies can get in the way), you could 'overload' 
POST by, for example, adding a query parameter _method=PUT to pass-thru the 
real request method.  The idea is that the handler would pick off this 
parameter and dispatch as though the HTTP method had really been PUT.  But 
you try to use this request like you would a 'real' PUT, in what the data 
contains and how it is used.


But this is a question I have, whether the REST dispatching modules have an 
capability like this, interpreting overloaded POSTs?


I added this to a custom Catalyst::Request subclass I use for my app. It 
looks like this:


 sub method
 {
 my $self = shift;

 return $self-NEXT::method(@_)
 if @_;

 return $self-{__method} if $self-{__method};

 my $method = $self-NEXT::method();

 return $method unless $method  uc $method eq 'POST';

 my $tunneled = $self-param('x-tunneled-method');

 return $self-{__method} = $tunneled ? $tunneled : $method;
 }


-dave

/*===
VegGuide.Orgwww.BookIRead.com
Your guide to all that's veg.   My book blog
===*/

___
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] REST - like uri design for CRUD

2008-01-20 Thread Thomas L. Shinnick

At 04:06 PM 1/20/2008, =?KOI8-R?B?88XSx8XKIO3B0tTZzs/X?= wrote:
  One important topic in the book is that 
people mix 'verbs' into their URIs

 when they shouldn't, or at least when they don't _have_ to.  Using the
 book's concepts your URIs would become
  1)  GET/class?pattern=breadbox
  2)  GET/class/id/
  3)  PUT/class/id/
  4)  POST /class
Nice clarification, thank you! But is the /id/ 
part of url required? In most cases class would 
have only one primary identifier, so we can 
shrink it to GET /class/ - can't we?


Oh definitely the naming URI's is very important, 
and can be intricate.  The authors develop on a 
couple different example application cases 
illustrating how they would layout the URI 
namespace.  And how they sometimes have to go 
back and redo the layout to eliminate conflicts.


Their essential criteria are that each URI 
specify one 'thing', and that every 'thing' have 
(at least) one URI.  That doesn't mean that a 
less-specific URI is not meaningful.  If 
/class/ is one item, you might still allow 
GET /class to mean get me the list of all items under /class.


And concerning case 3 - I think that rarely used 
PUT method could be replaced with common POST to 
avoid possible problems with proxies, etc. -- ó Õ×ÁÖÅÎÉÅÍ, óÅÒÇÅÊ íÁÒÔÙÎÏ×.


The authors do take care not to be so rigid we 
can't _try_ to approach the one true way of REST. :-)


They specifically allow that when PUT is not 
available or impracticable (clients, firewalls, 
and proxies can get in the way), you could 
'overload' POST by, for example, adding a query 
parameter _method=PUT to pass-thru the real 
request method.  The idea is that the handler 
would pick off this parameter and dispatch as 
though the HTTP method had really been PUT.  But 
you try to use this request like you would a 
'real' PUT, in what the data contains and how it is used.


But this is a question I have, whether the REST 
dispatching modules have an capability like this, 
interpreting overloaded POSTs? ___
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] REST - like uri design for CRUD

2008-01-20 Thread Daniel Hulme
On Mon, Jan 21, 2008 at 01:06:25AM +0300, Сергей Мартынов wrote:
 But is the /id/ part of url required? In most cases class would have
 only one primary identifier, so we can shrink it to GET /class/ -
 can't we?

In this case, we could, but often the identifier for a thing is a
character string rather than a string of digits, so you wouldn't want to
do that because it would break when you created objects named create, or
whatever your chained actions are called.

-- 
Every program eventually reaches a point where it becomes harder to make
a simple change than to rewrite the program from scratch. Unfortunately,
when this point is reached, it is far too late to consider rewriting it.
http://surreal.istic.org/Why did you resign?


signature.asc
Description: Digital signature
___
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] REST - like uri design for CRUD

2008-01-20 Thread Dave Rolsky

On Sun, 20 Jan 2008, Ashley wrote:

Clipped a bunch. This is great food for thought. I am missing in this scheme 
how you would know to serve the form for updating. That seems to be the real 
point of /class/id//update. I suppose that should be /class/id//edit 
instead and it would, if it could, properly PUT the form to /class/id/, 
yes?


What I've done is something like /user//edit_form

That makes it clear that the URI is a noun, the edit for for user . 
I still PUT to /user/ for the update. When I say PUT I really mean 
tunnel PUT via a POST, of course, because browser make this all so 
difficult.


For creation I'd have /user/create_form or /user/new_user_form and POST to 
/user



-dave

/*===
VegGuide.Orgwww.BookIRead.com
Your guide to all that's veg.   My book blog
===*/

___
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] REST - like uri design for CRUD

2008-01-20 Thread Thomas L. Shinnick

At 04:11 PM 1/20/2008, Ashley wrote:

On Jan 20, 2008, at 1:33 PM, Thomas L. Shinnick wrote:

At 01:56 PM 1/20/2008, Zbigniew Lukasiak wrote:

/class/search
/class/id//view
/class/id//update
/class/create


spew register=pedant
One important topic in the book is that people mix 'verbs' into 
their URIs when they shouldn't, or at least when they don't _have_ 
to.  Using the book's concepts your URIs would become


1)  GET/class?pattern=breadbox
2)  GET/class/id/
3)  PUT/class/id/
4)  POST /class
 /spew


Clipped a bunch. This is great food for thought. I am missing in 
this scheme how you would know to serve the form for updating. That 
seems to be the real point of /class/id//update. I suppose that 
should be /class/id//edit instead and it would, if it could, 
properly PUT the form to /class/id/, yes?

-Ashley


Rats, I can't pinpoint the area where they talk about this (serving 
forms) in the book.  Two points of departure:


First, there is a difference when talking about how you go about 
implementing RESTful interactions where both the client/server are 
programmed, that is, where data is exchanged directly and people 
aren't involved.  When you instead want to make accommodations for 
allowing more classical (non-Javascript) interactions it _does_ get 
cloudy.  And if you want to serve _both_ programmed and human 
interactions it gets positively foggy.  You don't want to start 
having alternate URIs just to specify what 'kind' of representations 
to serve.   So...


Second, if there are multiple representations for an item, how do we 
specify which representation is being requested?  The authors ask 
that you try to use something like the Accept: header, so that a 
Javascript program can specify that it wants an XML or JSON 
representation, _rather_ than an HTML form representation.  If you 
want to allow plain unenhanced browsers you could serve the form in 
HTML by default.  But if the request specifically said give me 
straight data, the server would see the Accept: application/json (I 
think that's right) and respond with Content-type: 
application/xml.  Program or person - the HTTP headers tell you which.


Now they again mention real-world hiccups, where some component might 
not pass-thru or pay attention to headers like Accept.  They offer 
that you could (if forced) specify the desired content type in either 
the query parameters or even the URI itself, where they suggest an 
extension.  Thus GET /class/1234.xml would be what a program might 
request, rather than a plain GET /class/1234 which might default to HTML.


Basically they keep coming back to the same theme: use HTTP to its 
fullest, both headers and methods (e.g. PUT), and much becomes 
possible that otherwise seems clumsy.   (Didn't say 'easy'... :-) ___
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] REST - like uri design for CRUD

2008-01-20 Thread Zbigniew Lukasiak
On Jan 20, 2008 10:33 PM, Thomas L. Shinnick [EMAIL PROTECTED] wrote:



 At 01:56 PM 1/20/2008, Zbigniew Lukasiak wrote:

 I know this has been discussed already - but I can't find it in the
 archives.

  What I conjured is:

  /class/search
  /class/id//view
  /class/id//update
  /class/create

  Update and create use really the same logic and templates - so I just
  forward to a create_or_update action from them.

  What are your opinions?

  --
  Zbigniew Lukasiak
  spew register=pedant

  The book RESTful Web Services has been very useful to me in understanding
 the confusion about what REST means when it comes to 'verbs'.  And that I'm
 interested in how close one can come to 'strict' REST design using Catalyst.

  One important topic in the book is that people mix 'verbs' into their URIs
 when they shouldn't, or at least when they don't _have_ to.  Using the
 book's concepts your URIs would become

  1)  GET/class?pattern=breadbox
  2)  GET/class/id/
  3)  PUT/class/id/
  4)  POST /class

While we are at that - I do understand the need to divide the
operations into the 'indempotent' and 'non-indempotent' classes
(because of caching and predictive link loading) - but what is really
the practical argument for having two more classes (PUT and DELETE)?

Cheers,
Zbigniew





  1) is your /class/search and says let me retrieve the
 representation/list of the items selected by searching for the given
 pattern, where the base URI would indicate the set/list of items, and the
 pattern is kept in the query parameters because it could be anything.  Note
 that the idea is that GET /class references the list of all items, and you
 here are just qualifying that search with the pattern.

  2) Your /class/id//view would be seen in strict REST as just a GET of
 /class/id/.  The HTTP 'verb' GET already says give me a representation
 of the item.  Done.

  3) Your /class/id//update would become a PUT of /class/id/,
 where the new representation coming from the remote client would _replace_
 the old representation/data for that item.  This strict use of the HTTP
 'PUT' verb is actually the hardest to accomplish, as it assumes that the
 remote client can receive and update a representation on the client, and
 then send it back using PUT.  It is easiest to picture this usage when the
 client completely replaces the old representation held on the server.  (see
 farther below for why)

  4) Your /class/create becomes a POST to /class.  This was another
 concept brought out by the book.  The matter of who determines the item's
 'id' is important.  Here we assume that the _server_ will determine the id
 of the new added item.  You do a POST to the base URI of the data area, and
 the server determines the new id, stores the data into the item, and does a
 redirect to tell the remote client where the new item is, that is, what is
 the new item's URI, for instance /class/id/1234.

  Why is who determines the id important?  Because it says what HTTP verb
 you should use to create a new item.  If the server, you use POST to add
 another item.  (Much discussion of that most misunderstood of HTTP
 methods: POST in the book)  But if the remote client were to determine the
 id, say because the id is a license plate number input at the client, then
 strict REST would say the client should do a PUT to /class/id/STRWBYP and
 the client would send the complete data for the item.  The server would
 create the item using the id 'STRWBYP as requested by the client.

  Creation using POST would say create a new item and tell me (the client)
 where you (the server) put it.  Creation using PUT defines where to put it
 to the server, because the client knows what the id should be.

  So under some designs it is possible that PUT will be used for both
 creation of new items and update (replacement) of existing items.  In both
 these cases (under such a design) the client knows the correct id for the
 item.

  Anyway this spew was prompted by the new pedant seeing 'REST' in the
 subject and then no mention of 'PUT', etc.  The book tries to be clear that
 it depends on both your design and the capabilities of the client
 whether you can implement using the strict REST HTTP verb set GET, PUT, and
 POST, or whether you must compromise on a REST-like set of GET and POST.
 The authors discuss how to overload POST to effect PUT-like usage, because
 we have to implement in the real world.  But they are clear about the goals
 of RESTful design, the problems it solves, and the benefits it brings in
 the real world.

  It looks to be very useful to consider URI design with a view towards how
 would I accomplish this by splitting my data objects into URI addressable
 data that can be manipulated using the full set of HTTP verbs GET, PUT, POST
 and HEAD.  (And not putting verbs into URIs that might be cached)

  /spew
 ___
 List: Catalyst@lists.scsys.co.uk
 Listinfo: