In a RESTful application, how do we differentiate

2019-02-14 17:13发布

问题:

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.

回答1:

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()"


回答2:

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