Понятно, что я немного запутался в том, как правильно использовать REST, основываясь на том, как крупные компании разрабатывают свои API-интерфейсы для REST.
Вы правы в том, что REST является системой сбора ресурсов. Это означает представительский государственный трансферт. Не очень хорошее определение, если вы спросите меня. Но основными понятиями являются 4 HTTP VERB и отсутствие состояния.
Важно отметить, что у вас есть только 4 VERBS с REST. Это GET, POST, PUT и DELETE. Ваш resendпример будет добавить новый глагол для REST. Это должен быть красный флаг.
Вопрос 1
Важно понимать, что вызывающая сторона вашего REST API не должна знать, что выполнение PUTвашей коллекции приведет к генерации электронной почты. Это пахнет утечкой для меня. То, что они могли знать, - то, что выполнение PUTмогло привести к дополнительным задачам, которые они могли бы запросить позже. Они узнают об этом, выполнив GETнедавно созданный ресурс. Это GETвернет ресурс и все Taskидентификаторы ресурса, связанные с ним. Позже вы можете запросить эти задачи, чтобы определить их статус и даже отправить новое Task.
У вас есть несколько вариантов.
REST - Подход, основанный на ресурсах задач
Создайте tasksресурс, в котором вы можете отправлять конкретные задачи в вашу систему для выполнения действий. Затем вы можете GETвыполнить задание на основе IDвозвращенного значения, чтобы определить его состояние.
Или вы можете смешать SOAP over HTTPвеб-сервис, чтобы добавить RPC в вашу архитектуру.
Запросы для всех задач для конкретного ресурса
GET http://server/api/myCollection/123/tasks
{ "tasks" :
[ { "22333" : "http://server/api/tasks/223333" } ]
}
пример ресурса задачи
PUT http://server/api/tasks
{
"type" : "send-email" ,
"parameters" :
{
"collection-type" : "foo" ,
"collection-id" : "123"
}
}
==> возвращает идентификатор задачи
223334
GET http://server/api/tasks/223334
{
"status" : "complete" ,
"date" : "whenever"
}
REST - использование POST для запуска действий
Вы всегда можете POSTдобавить дополнительные данные к ресурсу. На мой взгляд, это нарушит дух REST, но все равно будет соответствовать.
Вы можете сделать POST похожим на это:
POST http://server/api/collection/123
{ "action" : "send-email" }
Вы будете обновлять ресурс 123 из коллекции дополнительными данными. Эти дополнительные данные, по сути, являются действием, указывающим бэкэнду отправить электронное письмо для этого ресурса.
Проблема, с которой я столкнулся, заключается в том, GETчто ресурс на этом ресурсе вернет эти обновленные данные. Тем не менее, это решит ваши требования и все равно будет RESTful.
SOAP - веб-служба, которая принимает ресурсы, полученные от REST
Создайте новый WebService, в котором вы можете отправлять электронные письма на основе предыдущего идентификатора ресурса из REST API. Я не буду вдаваться в подробности о SOAP, поскольку первоначальный вопрос касается REST, и эти две концепции / технологии не следует сравнивать, так как это яблоки и апельсины .
вопрос 2
У вас также есть несколько вариантов здесь:
Похоже, что многие крупные компании, публикующие REST API, предоставляют searchколлекцию, которая на самом деле является просто способом передачи параметров запроса для возврата ресурсов.
GET http://server/api/search?q="type = myCollection & someField >= someval"
Который возвратил бы коллекцию полностью определенных ресурсов REST, таких как:
{
"results" :
{ [
"location" : "http://server/api/myCollection/1",
"location" : "http://server/api/myCollection/9",
"location" : "http://server/api/myCollection/56"
]
}
}
Или вы можете разрешить что-то вроде MVEL в качестве параметра запроса.
Вопрос 3
Я предпочитаю подуровни, чем возвращаться и запрашивать другой ресурс с параметром запроса. Я не верю, что есть какое-то правило, так или иначе. Вы можете реализовать оба способа и позволить вызывающим абонентам решать, какой из них более уместен, исходя из того, как они впервые вошли в систему.
Ноты
Я не согласен с читаемостью комментариев от других. Несмотря на то, что некоторые могут подумать, REST все еще не для потребления человеком. Это для машинного потребления. Если я хочу видеть свои твиты, я использую обычный веб-сайт Twitters. Я не выполняю REST GET с их API. Если я хочу программно что-то сделать со своими твитами, тогда я использую их REST API. Да, API должны быть понятными, но вы gteне так уж и плохи, просто они не интуитивно понятны.
Другая важная вещь в REST - это то, что вы должны иметь возможность начинать с любого заданного пункта в вашем API и переходить ко всем другим связанным ресурсам, БЕЗ знания точного URL других ресурсов заранее. Результаты GETVERB в REST должны возвращать полный REST URL ресурсов, на которые он ссылается. Таким образом, вместо запроса, возвращающего идентификатор Personобъекта, он возвращает полный URL-адрес, такой как http://server/api/people/13. Тогда вы всегда можете программно перемещаться по результатам, даже если URL изменился.
Ответ на комментарий
На самом деле в реальности существуют вещи, которые не должны создавать, читать, обновлять или удалять (CRUD) ресурс.
Дополнительные действия могут быть предприняты на ресурсах. Типичные реляционные базы данных поддерживают концепцию хранимых процедур. Это дополнительные команды, которые могут быть выполнены для набора данных. REST по своей сути не имеет этой концепции. И нет причин, по которым это следует. Эти типы действий идеально подходят для RPC или SOAP Web Services.
Это общая проблема, которую я вижу с REST API. Разработчикам не нравятся концептуальные ограничения, окружающие REST, поэтому они приспосабливают его к тому, что им нравится. Это ломает это от того, чтобы быть RESTful сервисом все же. По сути, эти URL-адреса становятся GETвызовами для псевдо-REST-подобных сервлетов.
У вас есть несколько вариантов:
- Создать ресурс задачи
- Поддержка
POSTдополнительных данных к ресурсу для выполнения действия.
- Добавьте дополнительные команды через веб-службу SOAP.
Если бы вы использовали параметр запроса, какой HTTP VERB вы бы использовали для повторной отправки электронной почты?
GET- Повторно ли отправляется электронное письмо И возвращаются ли данные ресурса? Что если система кэширует этот URL и обрабатывает его как уникальный URL для этого ресурса. Каждый раз, когда они нажимают на URL, они пересылают письмо.
POST - На самом деле вы не отправляли новые данные на ресурс, только дополнительный параметр запроса.
Исходя из всех данных требований, решение проблемы POSTс ресурсом с action fieldданными POST.