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

2008-01-29 Thread Ian Docherty

Aristotle Pagaltzis wrote:

* Ian Docherty [EMAIL PROTECTED] [2008-01-28 13:45]:
  

OK, so I put the item into the request body, but this does not
tell the remote client the ID of the created item.



Why does it need it? Is the URI not enough? If not, is the URI
*really* not enough (ie. could things be arranged so that it is)?
  
The 'create' is a POST to the URI http://mydomain.com/svc/doc with the 
content being
the document to save. However, the client has to know the ID of the 
created document

(which at this point is only known by the server).
  

Say for example that I am putting arbitrary documents (xml,
text, images) etc. onto the server via a web service in a
RESTful manner, I do this with a POST to my server. The server
needs to respond with something in the header to indicate the
ID of the document just POSTed.



Well, then don’t render the body of the item in the 201 response,
and do not set Content-Location, and instead just put some JSON
or XML or whatever in there.
  
OK, this would have been my first choice but I was misled I think by 
some other threads.
  

I do this in the Location header.



Location may only ever be a URI. If you put anything else there,
you’re doing it wrong.
  

Yes I agree.
  

e.g. POST /svc/upload (the document save)
Location /svc/view/1234 (the location of the item just saved, ID=1234)

So the URI is parsed by the programmatic client to extract the
'1234' yes/no?



No. Clients should never parse URIs. If you need to tell them
something they need to be able to understand, you put it in the
body.

(They should not construct URIs either. If they need to request
parametrisable URIs, the server should send them a form. Or if
you’re creating a non-browser HTTP API, you can send the client
a URI Template.)
  
This is something I have not seen mentioned before. I have no idea what 
a 'URI Template'
would look like. I don't see what is wrong with 'constructing' a URI, 
e.g. what is wrong
with the client 'knowing' that URI http://mydomain.com/svc/view/1234 is 
the location to

retrieve item 1234?

This is the hypermedia constraint in REST: clients only follow
links and forms. They don’t have any hardwired knowledge of the
server URI space.

(Note, though, that things get muddled with Ajax clients. If the
Ajax client is code served by the server (called _Code on Demand_
in REST), then it’s effectively a Turing-complete kind of form
markup, so it’s fine for that code to have hardwired knowledge.
But in practice, the Ajax client probably talks to a publically
available HTTP interface, and making that interface require hard-
wired knowledge of non-Code-on-Demand clients is wrong, so it’s
probably better to follow the hypermedia constraint even in on-
demand code.)

Regards,
  


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


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

2008-01-29 Thread Matt S Trout
On Tue, Jan 29, 2008 at 08:19:42AM +, Ian Docherty wrote:
 This is something I have not seen mentioned before. I have no idea what 
 a 'URI Template'
 would look like.

See the RFC and the CPAN module.

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

2008-01-25 Thread Pedro Melo

Hi,

On Jan 21, 2008, at 7:43 AM, Jonathan Rockway wrote:
Along these lines, how is everyone doing multi-page forms?  I like  
to do
GET/POST/redirect, but that needs the session to get the data from  
page

1 to page 2.  Without a session, I use the old POST returns the form
with hidden fields that is page 1, but i *hate* that technique.  So I
use the session.


I'm going through this as well right now, doing a small checkout- 
style multi-step form. The following is my current idea on how to  
deal with this. Its still a rough draft but I think it will work ok.  
Any feedback is appreciated.


Below, when I mention PUT, i'm using PUT-tunneled-over-POST for web  
clients.


Users start by POST'ing to /checkout/start. This will create a cart  
containing the items to include in this checkout. In our case, we  
always include all the items currently pending payment, other sites  
might have a different policy/requirements. The point of this first  
step is to create a cart, with a unique identifier. We associate the  
cart with the logged in user and we include a security hash based on  
the cart id and user id on each form. After all this, we redirect to / 
checkout/cart/UNIQUE_ID/step1.


On each step, the GET will show the appropriate form. The user will  
fill the fields, and PUTs the result to the same address. Information  
received is checked and valid fields are stored in the cart state.  
After that, if all fields are correct, we redirect to the next step.


If they are not correct, we redirect to the same URL. Previous  
values, and error messages or error codes are given back using URL  
parameters. Usually we have very little parameters and they are all  
limited in size, so it fits the 1k max URL size.


Aside: If a field is unusually large, we need some kind of temporary  
storage, and this could break somewhat the Idempotence of each  
request. We could sha1 hash the bad content, store it somewhere keyed  
on this hash and send the hash to the client. This might solve it.  
Fortunately I never needed this.


On each step, the process updates the fields on the cart, and at the  
final step, we change the status of the cart to 'ready_to_process'  
and redirect the user to a success page.


The things I like on this approach:

Every request is idempotent: you can reload to your hearts content  
any page, you can post several times each step to update previous  
entered information, you can go back and forward, everything.


There is no final step of copying the cart usually stored in the  
session to your orders table. The cart is the order, you build the  
order step by step until its ready to be processed by our back-office  
staff.


Old, unfinished orders can be cleaned up after some time, and if they  
are request in the future you can just create a new one and redirect  
to it, or you can give the user a error message and suggest the  
creation of a new one. I keep carts for one year or until the items  
in it expire, but that's my business :). Yours might need different  
timings. You could also erase old carts based on the step they are at.


If you start a new checkout with another one still open, there are  
several options. My personal choice is to merge the old order with  
the new items, but you could also create a new one and suggest  
merging the old one (merging on demand). This part also depends on  
your business needs.


Anyway, this is my currently thinking on this subject. Any feedback  
appreciated.




(I also use the Flash for You've added a record
successfully! messages.  Totally non-RESTful, but the users seem to
like it.)


You not redirect with parameters? something like  
po_id=1p1=Pedro[EMAIL PROTECTED] to use message id 1 with two  
parameters, 1=Pedro and [EMAIL PROTECTED]


RESTfull, no?

Best regards,
--
Pedro Melo
Blog: http://www.simplicidade.org/notes/
XMPP ID: [EMAIL PROTECTED]
Use XMPP!



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


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

2008-01-22 Thread Zbigniew Lukasiak
On Jan 22, 2008 8:25 AM, Zbigniew Lukasiak [EMAIL PROTECTED] wrote:
 On Jan 22, 2008 1:30 AM, Aristotle Pagaltzis [EMAIL PROTECTED] wrote:
  * Zbigniew Lukasiak [EMAIL PROTECTED] [2008-01-21 07:40]:
   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)?
 
  I don't understand this question. It sounds like you have some
  confusion about several distinct things and that you don't
  actually understand what idempotence is. Can you try to explain
  a bit more what you are trying to ask? Are you just asking why
  there are more verbs than GET and POST? Are you asking about why
  it's important to categorise verbs as non-/safe in addition to
  non-/idempotent? Is it something all together different?

 The first one.  Why you need to split the class of non-idempotent
 operations into three more categories (POST, PUT and DELETE).

Just after sending it I have realized that DELETE can be also viewed
as idempotent since a second call to it does not really change the
state (even if it can return an error to the caller).
And that shows another question - perhaps all we need is the simple
division into safe and non-safe operations?

--
Z.

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


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

2008-01-22 Thread Aristotle Pagaltzis
* Zbigniew Lukasiak [EMAIL PROTECTED] [2008-01-22 08:35]:
 On Jan 22, 2008 1:30 AM, Aristotle Pagaltzis [EMAIL PROTECTED] wrote:
  I don't understand this question. It sounds like you have
  some confusion about several distinct things and that you
  don't actually understand what idempotence is. Can you try to
  explain a bit more what you are trying to ask? Are you just
  asking why there are more verbs than GET and POST? Are you
  asking about why it's important to categorise verbs as
  non-/safe in addition to non-/idempotent? Is it something all
  together different?
 
 The first one.  Why you need to split the class of
 non-idempotent operations into three more categories (POST, PUT
 and DELETE).

* Zbigniew Lukasiak [EMAIL PROTECTED] [2008-01-22 11:10]:
 Just after sending it I have realized that DELETE can be also
 viewed as idempotent since a second call to it does not really
 change the state (even if it can return an error to the
 caller). And that shows another question - perhaps all we need
 is the simple division into safe and non-safe operations?


It seems to me you are still confusing several things.

“Idempotent” means that the request will have the same result if
you make it repeatedly. GET, PUT and DELETE are all idempotent:
no matter how often you repeat them, the resulting resource state
on the server will always be the same. This is important insofar
as if the request times out due to a network problem, say, the
client can simply retry it without any ill effects. This also
means proxies can retry such requests for you. POST is not
idempotent, in contrast.

“Safe” means the client may assume that the server will not do
anything harmful in processing the request, and if the server
does, the client is not responsible for it. GET is safe in
addition to being idempotent: clients may assume that they can
send GET requests and nothing terrible will happen. If you `GET
/all-my-data/delete` and the server deletes all your data, and it
should not have, then it’s the server’s fault, not the client’s.
This makes it possible to write things like search engines and
other web crawlers, f.ex.

Another reason to have separate PUT and DELETE is because without
them, you have to tunnel meaning through the body of POST, which
muddles things. The semantics of POST depend on the URI which is
being posted to, whereas the semantics of PUT are always clear:
the client asserts that the resource state should from now on
correspond to the request body entity. If the server decides to
process a PUT request to a URI, it is always clear what is going
to happen; if the server decides to process a POST request to a
URI, as a client, you have no idea what it will do.

Same reasoning goes for DELETE, and for the PATCH draft currently
being written.

Regards,
-- 
Aristotle Pagaltzis // http://plasmasturm.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] Re: REST - like uri design for CRUD

2008-01-22 Thread Peter Karman



Peter Karman wrote on 1/20/08 7:53 PM:



Aristotle Pagaltzis wrote on 1/20/08 7:36 PM:

* Peter Karman [EMAIL PROTECTED] [2008-01-20 22:10]:

there's no checking of HTTP method at all.


Yikes!!

img src=http://example.org/foo/id/42/delete;




I actually consider that a feature, since it seems legit to me that a GET could 
act on an object. That's not REST, but RPC, as you indicated. In my apps, I do 
server-side auth checks to verify that users can't act on data they should not 
have access to. Then again, all my apps use POST to delete too. :)


That said, I did enable a method-check in v0.23 with a configuration option to 
turn it off.



That API is intentionally RESTish


It’s not REST if it ignores the uniform interface – it’s RPCish.
URI design is completely orthogonal to REST.



you are right of course.

/me adds CatalystX::CRUD::REST to todo list...



/me crosses item off list

http://search.cpan.org/~karman/CatalystX-CRUD-0.23/lib/CatalystX/CRUD/REST.pm

Thanks, Aristotle, for pointing out my naive understanding of REST. This thread 
helped me write the API in the module above.


Comments, suggestions always welcome.

pek

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

2008-01-22 Thread Christopher Laco

Aristotle Pagaltzis wrote:

* Peter Karman [EMAIL PROTECTED] [2008-01-23 03:50]:

In my apps, I do server-side auth checks to verify that users
can't act on data they should not have access to.


Peter, meet XSRF. XSRF, meet Peter.

:-)

My point with `img src=/foo/delete` was that an attacker
tries to get an authenticated and authorised user to visit a
page which contains that tag.

Or maybe an authenticated and authorised user has software like
the Google Web Accelerator installed.

Regards,



But surely the same is true for POST as well using a form/javascript.
So what does that leave?



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/


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

2008-01-21 Thread Aristotle Pagaltzis
* Zbigniew Lukasiak [EMAIL PROTECTED] [2008-01-21 07:40]:
 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)?

I don’t understand this question. It sounds like you have some
confusion about several distinct things and that you don’t
actually understand what idempotence is. Can you try to explain
a bit more what you are trying to ask? Are you just asking why
there are more verbs than GET and POST? Are you asking about why
it’s important to categorise verbs as non-/safe in addition to
non-/idempotent? Is it something all together different?

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

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


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

2008-01-20 Thread Aristotle Pagaltzis
* Peter Karman [EMAIL PROTECTED] [2008-01-20 22:10]:
 there's no checking of HTTP method at all.

Yikes!!

img src=http://example.org/foo/id/42/delete;


 That API is intentionally RESTish

It’s not REST if it ignores the uniform interface – it’s RPCish.
URI design is completely orthogonal to REST.

Regards,
-- 
Aristotle Pagaltzis // http://plasmasturm.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] Re: REST - like uri design for CRUD

2008-01-20 Thread Peter Karman



Aristotle Pagaltzis wrote on 1/20/08 7:36 PM:

* Peter Karman [EMAIL PROTECTED] [2008-01-20 22:10]:

there's no checking of HTTP method at all.


Yikes!!

img src=http://example.org/foo/id/42/delete;



That API is intentionally RESTish


It’s not REST if it ignores the uniform interface – it’s RPCish.
URI design is completely orthogonal to REST.



you are right of course.

/me adds CatalystX::CRUD::REST to todo list...

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

2008-01-20 Thread Jonathan Rockway

On Sun, 2008-01-20 at 23:58 -0600, Dave Rolsky wrote:
 On Mon, 21 Jan 2008, Aristotle Pagaltzis wrote:
 
  The part where web browsers really do suck – and I really mean
  suck utterly terribly – is HTTP Auth, which makes you have to…
  well, you don’t quite have to violate REST constraints, but you
  are forced to traipse into grey areas like cookie-based auth (not
  sessions!).
 
 I think sessions _can_ be RESTful if they are part of the URI, though you 
 probably wouldn't want to use them for auth.
 
 I _do_ use sessions in VegGuide.Org in what I think is a RESTful way. 
 Certain redirects will send you to a URI like 
 http://www.vegguide.org/user/login_form/-/a746d3cba351bde58debde610b40715d49ec4312
 
 This user represents a unique thing, which is the login_form + a session. 
 I only use the session to hold very transient things, like error or 
 success messages after a form submission. In the case of an error, it also 
 holds the state of the form so we can repopulate it.

Along these lines, how is everyone doing multi-page forms?  I like to do
GET/POST/redirect, but that needs the session to get the data from page
1 to page 2.  Without a session, I use the old POST returns the form
with hidden fields that is page 1, but i *hate* that technique.  So I
use the session.  (I also use the Flash for You've added a record
successfully! messages.  Totally non-RESTful, but the users seem to
like it.)

Regards,
Jonathan Rockway



signature.asc
Description: This is a digitally signed message part
___
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/