In a RESTful application, how do we differentiate between an "action" and an HTTP verb (GET
, POST
, PUT
, DELETE
)?
For example, as I understand it, a GET
request to the resource /products
should return a list of all products. A POST
request to /products
should create a new product. How, then, does the user request the original form which is used to create the product? My initial response would have been a GET
request to the same URI, but as mentioned above, that should return a list of all products - not a blank form for creating a product.
In most frameworks I've researched, this problem is solved by making the "action" part of the URI. For example, a POST
request to /products/create
would create a new product, whereas a GET
request to /products/create
would give the blank form for creating a product. To get a list of all products would be a GET
request to either /products
or /products/get
, /products/read
, etc. depending on the framework in question. This approach resolves the ambiguity above, but it conflicts with what I've read about traditional REST design.
IMHO, the best option is to make the request method a part of controller's action.
Lets say you are accessing http://who.cares/product/42
or http://who.cares/product/42/specification
. This query to webserver would translate as Product
controller. The actions name should be created by combining request method and command:
DELETE "http://who.cares/product/42"
controller: "Product",
action: "deleteProduct()"
GET "http://who.cares/product/42/details"
controller: "Product",
action: "getDetails()"
POST "http://who.cares/product/42/review"
controller: "Product",
action: "postReview()"
GET "http://who.cares/products/
controller: "Products",
action: "getProducts()"
POST "http://who.cares/products/
controller: "Products",
action: "postProducts()"
here is example like it Rails does
REST request path | action name | Description
---------------------|-------------------|-------------
GET /profile/new | new | Render a form for creating the profile
POST /profile | create | Create a the profile from the received data
GET /profile | show | Render a the profile
GET /profile/edit | edit | Render a form for editing the profile
PUT /profile | update | Update the profile based on the received data
DELETE /profile | destroy | Destroy the profile
I don't see any conflict , Idea is that
urls are human readable and you can introduce new URIs to show different representations of the same resource. (like profile/1/edit and profile/1)
/profile/new - address of profile that is empty (like profile/1, profile/2 .. etc in show method)
But if you want you can suggest that profile/1/edit is some kind of different - nested resource of profile/1/ resource, but I like to thing that it's just other representation of profile/1/ resource =)
Also is good idea to use plural and singular URI when you working with many resources or with one, example
/profile/1.html - gives you 1 resource
/profiles.html - gives you list of profiles