Зрозуміло, що слід трохи заплутатися в тому, як правильно використовувати REST на основі всіх способів, якими я бачив, як великі компанії проектували свої REST API.
Ви вірні в тому, що REST - це система збору ресурсів. Він розшифровується як державна передача представництва. Не чудове визначення, якщо ви запитаєте мене. Але основні поняття - це 4 HTTP VERB і вони без громадянства.
Важливим елементом є те, що у вас є лише 4 СЕРБИ з REST. Це GET, POST, PUT та DELETE. У вашому resendприкладі буде додавання нового дієслова до REST. Це повинен бути червоний прапор.
питання 1
Важливо усвідомити, що абонент вашого API REST не повинен знати, що виконання 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 з колекції додатковими даними. Ці додаткові дані по суті є дією, яка сповіщає бекенду відправити електронний лист для цього ресурсу.
Проблема у мене полягає в тому, що a GETна ресурсі поверне ці оновлені дані. Однак це вирішило би ваші вимоги та все-таки буде ВІДБУДАТИ.
SOAP - Веб-сервіс, який приймає ресурси, отримані від REST
Створіть нову WebService, в якій ви можете надсилати електронні листи на основі попереднього ідентифікатора ресурсу з API REST. Я не буду вникати в деталі про 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.
Це загальна проблема, яку я бачу з API REST. Розробникам не подобаються концептуальні обмеження, які оточують REST, тому вони адаптують його до того, щоб вони хотіли. Це відриває його від того, що вона є РЕЙТЕЛЬНОЮ службою. По суті, ці URL-адреси стають GETвикликами псевдо-REST-подібних сервлетів.
У вас є кілька варіантів:
- Створіть ресурс завдання
- Підтримка
POSTдодаткових даних до ресурсу для виконання дії.
- Додайте додаткові команди через веб-сервіс SOAP.
Якщо ви використовували параметр запиту, який HTTP VERB використовували б для повторного надсилання електронної пошти?
GET- Це повторно надсилає електронну пошту І повертає дані ресурсу? Що робити, якщо система кешувала цю URL-адресу і розглядала її як унікальну URL-адресу для цього ресурсу. Кожен раз, коли вони потрапляють на URL-адресу, він надсилатиме електронний лист.
POST - Ви фактично не надсилали на ресурс ніяких нових даних, а лише додатковий параметр запиту.
Виходячи з усіх заданих вимог, завдання POSTна ресурсі з action fieldданими POST вирішить проблему.