RESTful действия / услуги, которые не соответствуют сущности? - PullRequest
13 голосов
/ 22 июня 2011

Мне нравится RESTful за его простоту и то, как он избегает бесполезности обычных «корпоративных» систем, таких как SOAP, или двоичной жесткости DCOM и RPC.

Но REST кажется более подходящим для объектов базы данных, чем болееабстрактные услуги.Мне было интересно, не могли бы вы посоветовать мне, как бы вы поступили в таких ситуациях:

Например, предположим, у меня есть веб-сервис RESTful для обычной системы баз данных (скажем, молочного магазина), поэтому ябыло бы / продукты / яйца / батареи и / продукты / молоко / обезжиренное

Выполнение INSERT было бы достигнуто путем создания POST для /products/eggs.

Но как бы вы сделаликоманда "очистить все"?Глагол DELETE подходит только для отдельных лиц.А «УДАЛИТЬ / продукты / молоко» подразумевает удаление самой категории продуктов «молоко», а не только всех продуктов в категории «молоко».А что, если вы хотите выполнить и то и другое?

Другой вопрос, который у меня возник, касается действий веб-службы, которые не связаны с сущностью.Например, если я разрабатываю веб-сервис для базы данных паролей, у меня были бы такие операции, как «GET /passwords/stackoverflow.com», что хорошо, но у меня также были бы операции по отключению веб-сайта в случае вторженияобнаружение.В модели веб-службы «старой школы» у меня был бы метод, называемый просто «disableWebsite», однако я не могу создать HTTP-глагол с именем «DISABLE» и ресурс «/ website» (поэтому запрос будет «ОТКЛЮЧИТЬ / сайт ").Какое здесь решение?

Наконец, как вы согласовываете HTML-формы с RESTful?Веб-формы могут только делать запросы GET, используя строки запросов или POST.Если у меня есть форма поиска, я хочу, чтобы она запросила «/ products / search / {query}», но сейчас запрос будет выглядеть как «/ products / search? Query = {query}».

Ответы [ 3 ]

5 голосов
/ 22 июня 2011

Я думаю, вы должны перестать думать о ресурсах как об синонимах для объектов базы данных. Да, они часто связаны, но ресурс - это просто адресуемая концепция в вашем домене. Я думаю, что гораздо полезнее думать о ресурсах как о вещах, которые вы видите в Интернете, когда используете браузер (списки, элементы, сообщения, комментарии, изображения и т. Д.).

Но как бы вы выполнили команду "очистить все"?

Я не уверен, почему DELETE / products / milk подразумевает удаление самой категории молока, но если вы предпочитаете:

DELETE /products?category=milk

УДАЛЕНИЕ не подразумевает удаление одного объекта базы данных. Это подразумевает удаление одного ресурса. И "/ products? Category = milk" (или "/ products / milk", в этом отношении) идентифицирует единственный ресурс. Если вы можете получить его, вы можете удалить его.

А что, если вы хотите выполнить оба?

Как насчет этого?

DELETE /product-categories/milk

Одна из хитростей, которая стала популярной в Ruby on Rails, - предоставить форму (используя GET) для любой операции PUT / POST / DELETE. Таким образом, для этих удалений вы можете предоставить следующую форму:

GET /product-categories/milk/delete

В этой форме (например, HTML) вы могли бы спросить своего пользователя, действительно ли можно удалить всю категорию. (Пожалуйста, не обращайте внимания на то, что формы HTML на самом деле не совместимы с веб-сервисами RESTful. HTML это довольно успешный формат для взаимодействия с ресурсами в Интернете, и хорошо спроектированное AJAX-приложение, вероятно, сначала работает как хорошо спроектированное HTML-приложение. Есть некоторые детали, которые необходимо проработать для поддержки как браузеров, так и других ваших клиентов, но все они законные клиенты REST.)

Как отключить сайт?

Есть много способов сделать это. Может работать только PUT на /sites/stackoverflow.com с флагом отключения.

Наконец, как вы согласовываете HTML-формы с RESTful?

Вы действительно не можете сделать HTTP PUT или DELETE из браузера, но вы можете предоставить скрытое поле в вашей форме, чтобы подделать его:

<input type="hidden" name="_method" value="PUT" />

Пока ваш механизм маршрутизации поддерживает это, это хороший способ направить сообщение браузера в соответствующий обработчик (я также видел, как люди используют заголовок X-HTTP-Method-Override для клиентов, не являющихся HTML, без полного поддержка HTTP-глаголов).

Если вы заинтересованы в поиске, я рекомендую Web Services Cookbook для начинающих. Также взгляните на модель зрелости Ричардсона 1042 *. И помните, что REST похож на остальную часть Интернета. Это было бы не очень полезно без ссылок. Предоставьте своим клиентам способ обойти.

<a href="/products/milk/delete" rel="delete" />

<atom:link href="/products/milk/delete" rel="delete" />
4 голосов
/ 22 июня 2011

RESTful-системы взаимодействуют с «ресурсами», которые не коррелируют со стандартным понятием сущности.
«Ресурс» - это очень нечеткая концепция с несколькими строгими правилами. Мне нравитсяпод ресурсом следует понимать любую полезную концепцию, которая может помочь клиенту делать то, что ему нужно.Итак, если вам нужно удалить группу сущностей, то создайте ресурс, который представляет эту «кучу сущностей», а затем используйте для него метод DELETE.

Настоящий трюк при проектировании спокойных систем - прекратить попыткиприсвоить значимость конкретным ресурсам, но присвоить значимость взаимосвязи между двумя ресурсами .Подумайте, как работает HTML.Вы загружаете страницу, и есть ссылка на таблицу стилей.Rel = "stylesheet" определяет значение того, что вы найдете в конце URL-адреса href.
Если вы хотите отключить веб-сайт, зайдите на ресурс веб-сайта и используйте URL-адрес, указанный в ссылке, с rel ="Disabler". RESTful дизайн - это определение ресурсов, которые связаны через ссылки .Некоторые ссылки используются только для поиска информации, другие фактически используются для внесения изменений в состояние ресурса.

Строгие правила, которым должен следовать ресурс, это то, что ресурс должен иметь идентификатор (например, URL), и вы можете взаимодействовать с этим ресурсом только через «представления» этого ресурса.Эти представления могут быть в широком диапазоне различных форматов.

Что касается HTML-форм, забудьте о том, как выглядит URI , использование параметров строки запроса так же RESTful, как и параметры пути.HTML-формы позволяют вам выполнять операции GET и POST, т.е. безопасные операции и небезопасные операции.Этого достаточно для любого, чтобы сделать ОТДЫХ.Конечно, DELETE и PUT могут быть полезны, но в действительности преимущества, которые эти дополнительные методы приносят системе RESTful, очень малы по сравнению с чем-то вроде гипермедиа.

2 голосов
/ 22 июня 2011

Но как бы вы выполнили команду «очистить все»? Глагол DELETE подходит только для отдельных лиц.

Ложные.

А «УДАЛИТЬ / продукты / молоко» подразумевает удаление самой категории продуктов «молоко», а не только всех продуктов в категории молока.

Correct.

А что, если вы хотите выполнить оба?

Что не так с DELETE на /cart/milk/?

В рамках модели веб-службы «старой школы» у меня был бы метод, называемый просто «disableWebsite»,

Что?

однако я не могу создать HTTP-глагол «DISABLE» и ресурс «/ website» (поэтому запрос будет «DISABLE / website»). Какое здесь решение?

POST. POST к /passwords/stackoverflow.com/disable/ Сущность (passwords/stackoverflow.com) содержит в себе дочернюю сущность «отключить» и «включить». Вы можете опубликовать любой из них, чтобы изменить состояние родительского объекта.

Если у меня есть форма поиска, я хочу ее запросить "/ products / search / {query}"

Вот почему большинство веб-сервисов RESTful написаны на Javascript или Flex или что-то в этом роде.

Веб-службы RESTful и «нативные» HTML-формы на самом деле не совместимы. Они не предназначены для этого.

...