В приложении RESTful, как мы различаем "действие" и HTTP-глагол (GET, POST, PUT, DELETE)?

В приложении RESTful, как мы различаем "действие" и глагол HTTP (GET, POST, PUT, DELETE)?

Например, насколько я понимаю, GET запрос к ресурсу /products должен вернуть список всех продуктов. POST запросить /products должен создать новый продукт. Как тогда пользователь запрашивает оригинальную форму, которая используется для создания продукта? Мой первоначальный ответ был бы GET запрос к тому же URI, но, как упоминалось выше, который должен вернуть список всех продуктов, а не пустую форму для создания продукта.

В большинстве фреймворков, которые я исследовал, эта проблема решается путем включения "действия" в URI. Например, POST запросить /products/create создаст новый продукт, тогда как GET запросить /products/create даст пустую форму для создания продукта. Чтобы получить список всех продуктов будет GET запрос либо /products или же /products/get, /products/readи т. д. в зависимости от рассматриваемой основы. Этот подход разрешает неоднозначность выше, но он противоречит тому, что я читал о традиционном дизайне REST.

2 ответа

Решение

ИМХО, лучший вариант - сделать метод запроса частью действия контроллера.

Допустим, вы получаете доступ http://who.cares/product/42 или же http://who.cares/product/42/specification, Этот запрос к веб-серверу будет переводиться как Product контроллер. Имя действия должно быть создано путем объединения метода запроса и команды:

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

Вот пример, как это делает Rails

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

Я не вижу никакого конфликта, идея в том, что URL читаются человеком, и вы можете ввести новые URI для отображения разных представлений одного и того же ресурса. (например, profile/1/edit и profile/1) /profile/new - адрес пустого профиля (например, profile/1, profile/2 и т. д. в методе show) Но если вы хотите, вы можете предложить этот профиль / 1 / edit - это какой-то другой вложенный ресурс профиля / 1 / ресурса, но мне нравится то, что это просто другое представление профиля / 1 / ресурса =)

Также хорошей идеей является использование множественного и единственного URI, когда вы работаете со многими ресурсами или с одним, например

/profile/1.html - gives you 1 resource
/profiles.html - gives you list of profiles
Другие вопросы по тегам