Зрозуміло, що слід трохи заплутатися в тому, як правильно використовувати 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-адреси інших ресурсів. Результати GET
VERB в 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 вирішить проблему.