Як створити API REST для обробки операцій, що не стосуються CRUD?


11

Я намагаюся перетворити набір послуг на основі SOAP в API RESTful.

Я почав з ідентифікації ресурсів, аналізуючи назви операцій, і отримав ресурс Subscription.

Коли мені потрібно оновити стан підписки, я не можу просто надіслати POSTзапит на сервер, оскільки у мене немає прямого доступу до ресурсів, але мені потрібно зателефонувати до деяких операцій у стилі RPC, щоб оновити їх властивості. Крім того, лише і якщо я змінюю стан передплати на "активний", потрібен додатковий дзвінок на зовнішню службу.

У яких випадках найкраща практика поводження з основними операціями?

Я запропонував рішення - використовувати параметри запиту, так що якщо мені потрібно зателефонувати в службу активації, я можу використовувати щось на зразок:

POST /subscriptions/{subscriptionid}/?activate=true

Зважаючи на те, що я не можу безпосередньо оновлювати свої об’єктні поля підписки, чи є найкраща практика для такого перетворення?

Оновлення 1:

Я можу помістити в тіло мого POST запит деяких значень, наприклад "state": "active"

і перевірити в моїй службі належні операції, які слід запустити.


Зіставлення команд REST на HTTP дієслова не вдається зі складними операціями. Вам краще просто зробити дзвінок у стилі RPC POST activateSubscription / {id} ніхто не буде плутати
Еван

@Ewan Я не впевнений, що це відповідає моделі RESTful, але я придумав інше рішення: у своєму коді я можу викликати належну операцію в стилі RPC відповідно до вхідної корисної навантаження (я можу передати state = active в тілі мій запит на пошту, код буде називати код активації)
Vektor88

1
Оновлення існуючого ресурсу, подібного до цього, має бути PATCH, і тіло запиту - це часткова модель того, що ви змінюєте. POST повинен бути запитом, який створює ресурс. Ця відмінність, окрім того, що буде зрозумілішою для користувача, полегшить ваш код, коли ця операція відбувається, а не повідомлення про ресурс.
Містер Кохез

1
@ Vektor88 Як правило, але це самовпевнені операції, де вам потрібно пройти в усьому представництві стану ресурсу. Цей випадок використання набагато більше схожий на часткове оновлення, яке дуже добре відповідає PATCH.
Містер Кокез

1
@MrCochese POST не є ідентичним.
JimmyJames

Відповіді:


8

Вам потрібно подивитися цю розмову Джима Вебера.

Коли мені потрібно оновити стан підписки, я не можу просто надіслати запит POST на сервер, оскільки у мене немає прямого доступу до ресурсів, але мені потрібно зателефонувати до деяких операцій у стилі RPC, щоб оновити їх властивості. Крім того, лише і якщо я змінюю стан передплати на "активний", потрібен додатковий дзвінок на зовнішню службу.

Подумайте "повідомлення"; надішліть повідомлення на свій домен, описуючи те, що ви хочете, щоб сталося. Побічним ефектом повідомлення є те, що модель домену фактично змінює свій стан. "Ресурс" - це черга повідомлень.

POST /subscriptions/{subscriptionid}/?activate=true

Правопис назви ресурсу не має значення для машин; але люди, як правило, метушаться, коли використовувані вами ідентифікатори відриваються від умовності, що ресурси - це "іменники".

Крім того, ми говоримо про підпорядкований ресурс /subscriptions/{subscriptionid}, тому конвенція (див. RFC 3986 ) вимагає виразити цей зв'язок із сегментом шляху, а не використовувати частину запиту.

Тож ці написання можуть бути розумними

POST /subscriptions/{subscriptionid}/messages
POST /subscriptions/{subscriptionid}/activations

1
Розмова Джима Вебера доступна на youtube.com/watch?v=aQVSzMV8DWc
користувач674669

0

Якщо його булевий прапор для активації / деактивації речей, я б сказав, що за замовчуванням використовується JSON:

POST /subscriptions/{subscriptionid}/
{
    format: 0,
    subscription: 
    {
        active: false
    }
}

Це легко розширюється, якщо ви хочете підтримувати більше властивостей. Інший підхід - це надання йому власної кінцевої точки:

POST /subscriptions/{subscriptionid}/active/
DELETE /subscriptions/{subscriptionid}/active/

Особисто я би використовував це лише у тому випадку, коли activeстан цієї події потребує / має властивості, які ви потім зможете передати / отримати в JSON, як ідентифікатор користувача або налаштування.

Якщо це не булеве значення, а просто дія, яку потрібно запустити, але не потрібно / мати будь-який зворотній зв'язок стану (за винятком негайного 200 ОК), я б використав кінцеву точку, подібну до цієї, щоб запустити її, як RPC:

POST /subscriptions/{subscriptionid}/activate/

Якщо ви сумніваєтесь, прочитайте це: http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api#restful (див. "Що з діями, які не вписуються у світ операцій CRUD? ")


0

REST - нефункціональний. Activateє дієсловом і не може бути державою, Activeє державою.

Оскільки RESTful є нефункціональним, ви не можете сказати службі RESTful, що робити, але ви можете додати роботу для черги служби.

Дивіться це:

PUT /subscriptionQueue
subscriptionId={subscriptionId}
active=true

Цей запит є RESTful і підтримує всі переваги RESTful (наприклад, продуктивність, кислота ...)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.