views:

240

answers:

4

The agavi framework uses the PUT request for create and POST for updating information. Usually in REST this is used the other way around (often referring to POST adding information while PUT replacing the whole data record).

If I understand it correctly, the important issue is that PUT must be idempotent, while POST does not have this requirement. Therefore, I wounder how creating a new record can be idempotent (i.e. multiple request do not lead to multiple creations of a record) in particular when usually the ORM uses an id as a primary key and the id of a new record would not be known to the client (since it is autocreated in the database), hence cannot be part of the request. How does agavi maintain the requirement of idempotence in light of this for the PUT request.

Thanks.

A: 

PUT can be used to create a resource, except that if the resource already exists (or has already been created by a previous PUT) it will just update it. POST should not update resources, however, if this is simple CRUD. Note that the HTTP verbs do not have a defined mapping to certain actions necessarily, since they're useful for a lot more than just CRUD.

Also note that this question has nothing to do with REST - just proper HTTP usage. So please remove the REST tag.

Wahnfrieden
Thanks for your answer. My question was asking if agavi is using REST appropriately, hence the tag.
txwikinger
Anyway I retagged to remove the REST tags - I think you have a mistaken interpretation of REST. What you really mean here is "if agavi is using HTTP appropriately."
Wahnfrieden
+4  A: 

PUT can be used both for creation and for updating complete records. POST is usually used for partial updates and related operations as well as for creating a new type of record on the server without specifying a URL for the resource (e.g. POST to /articles/23/comments returns a 201 status and a Location: /articles/23/comments/283136 header). So in your case (with a sequence/autoincrement ID), you would use that approach.

However, HTML (and thus web forms) is different. It only knows GET and POST, not DELETE and PUT. For deletion and updating operations, it overloads the POST method.

That's why Agavi, by default, maps POST to "write" and GET to "read" - it's the most common use case, and "read" and "write" were chosen because they are relatively neutral and also in a way represent the safety aspects of GET vs POST (safety as in "GET can be called without side effects" and blah).

You can change the mapping of verbs for the AgaviWebRequest implementation in factories.xml; refer to the Agavi users mailing list or the IRC channel if you need help with that (or ask away here). A lot of people on the IRC channel are also quite experienced with URL scheme design in case you need more help with making your API pretty.

dzuelke
Thanks for your answer. Yes, I saw some instructions in how to change it in the factories.xml file. I was interested to know why rails and agavi are different in their approach. I think, your answer has given me a new perspective for this question.
txwikinger
To clarify, you should specify "HTML 4.01" since the working draft of HTML5 adds other HTTP verbs to webforms.
Wahnfrieden
+2  A: 

Instead of thinking of PUT as creating, think of it as "putting". You put a resource at a URI (ie send an entire resource to a URI).

PUT http://example.com/articles/1

If you repeat this (send the same entire resource to the same URI) you get the same result and you haven't changed the resource at that URI, that's what makes it idempotent.

If agavi's implementation of PUT is idempotent then it is implementing PUT correctly. Otherwise it's not.

rojoca
Thanks for your answer. The question if agavi's PUT is idempotent is exactly what I trying to figure out.
txwikinger
A: 

Hi,

I've had this problem before. This can be solved by changing the factories.xml.

Regards,

[ simon.cpu ]

simoncpu
Thanks for your answer. I know about the factories.xml configuration. I am/was interested in the principle, how it should be done correctly, since different frameworks seem to do it differently.
txwikinger