Як описати архітектурну зміну, яка навмисно порушує стандарти REST?


37

Я пропоную зміни в дуже погано зосередженому програмному проекті, який страждає від безлічі проблем. На високому рівні проект використовує Angular на передній частині та споживає різні API REST; що все чудово (я не бачу необхідності змінювати нашу технологію чи інструменти). Проблема полягає в тому, що база коду непропорційно більша в інтерфейсі, ніж API на стороні сервера. Значна частина бізнес-логіки живе в інтерфейсі користувача, а API REST - це прості інтерфейси бази даних CRUD до рівня користувальницького інтерфейсу.

Наприклад, POST для клієнта створить запис клієнта, тоді як PUT модифікує цього клієнта. Не набагато більше, і не набагато менше. Однак наша логіка бізнесу є більш вимогливою. Загальний процес створення клієнта робить набагато більше, ніж вставляє 1 запис бази даних. Він надасть дані в інших необхідних таблицях, виконає певні перевірки та обчислення тощо. Я вважаю за краще зробити один виклик POST / PUT, який інкапсулює всю цю поведінку, полегшуючи навантаження споживача.

Отже, моя точка зору полягає в тому, що ця всебічна оркестрація повинна жити на сервері (де ми маємо повний контроль, журнали тощо), а не в інтерфейсі користувача, але одна зустрічна аргументація полягає в тому, що такий підхід вже не буде RESTful. Тож я не впевнений, як найкраще описати такий підхід, коли моя рекомендація - продовжувати існуючий стек технологій, але впроваджувати фундаментальні зрушення в місцях, де належить код.


44
Обмеження API на виклики CRUD задля того, щоб зробити його "RESTful" - це поганий компроміс.
Роберт Харві

38
@EsbenSkovPedersen: Кращий друг назавжди?
Роберт Харві

5
Замість того, щоб турбуватися про те, чи відповідає ваша послуга REST (iirc, майже нічого не роблять), я б більше потурбувався про відповідність специфікації HTTP . Більшість api, з якими я працював, також не відповідають специфікаціям, але це більш досяжна і гідна ціль imo.
aaaaaa

7
@aaaaaa, причина REST майже не відповідає послугам в тому, що ніхто не може вирішити, що таке REST. Єдиний пункт згоди, який я знайшов, - це "всі інші роблять неправильно".
Марк

16
- "Як описати архітектурний зсув, який навмисно порушує стандарти REST?" - неуважність . ( Вибачте за непрофесійний коментар, він був сильніший за мене. )
luk32

Відповіді:


49

Я не впевнений, як найкраще описати такий підхід, коли моя рекомендація - продовжувати існуючий стек технологій, але впроваджувати принципові зрушення у місцях, де належить код.

Service oriented architecture.

Ви пропонуєте переробити свою систему, щоб правила вашого бізнесу та ваші дані були в одному місці. Це фактично визначення послуги ; див. розмову Уді Дахана про пошук меж обслуговування .

Бічна панель: як зазначив Ерік, це не має нічого спільного з "REST". Не існує абсолютно жодної причини, що ви не можете поставити API REST (тобто API, що задовольняє обмеженням архітектурного стилю REST ) перед вашим сервісом. Але це може бути не очевидним для людей, які розуміють, що REST означає відображення операцій з базами даних методами HTTP.

Це може бути, а може і не варто інвестувати в зміну розуміння вашою аудиторією REST.


32
Також не варто взагалі інвестувати в REST. Якщо ви читаєте дисертацію Роя Філдінга (або Як я пояснив REST своїй дружині ), справжня мета REST - забезпечити канонічне представлення ресурсів в Інтернеті, щоб розрізнені машини через Інтернет мали стандартний спосіб маніпулювати цими ресурсами . Приватна програма може навіть не потребувати цієї можливості.
Роберт Харві

29

REST - це не CRUD. Цей "контраргумент" базується на принципово хибному розумінні того, що таке REST. У вашій публікації я не бачив нічого, що вказувало б на те, що ваша зміна зробила б ваш API більш-менш РЕСТЕВНІМ.


6
Ну, ні, це не ідеальне відображення до CRUD, але воно ходить, розмовляє та співає дуже схоже на CRUD, принаймні так, як трактує це більшість людей.
Роберт Харві

11
@RobertHarvey Я думаю, що саме тут (помилкове) розуміння.
JimmyJames

4
@JimmyJames: Це повсюдне непорозуміння. Існує сильний потяг зробити речі "спокійними", коли більшість людей навіть не розуміють, які переваги є, і як ці переваги будуть застосовуватися до них.
Роберт Харві

4
@RobertHarvey Я думаю, ти кажеш, що якщо робити це не так, це REST, то REST не має бути метою. Добре, але, як я це бачу, називати це "не ВІДБУТ" - це фігня, і я є великим прихильником заклику глупоти на фігнях. Слова потребують загальнозрозумілого значення, щоб бути корисним.
JimmyJames

5
@RobertHarvey Зрозуміло, але це не відбудеться до тих пір, поки буде достатньо людей, які бажають виправити ці зловживання терміном. Я не готовий кинути рушник.
JimmyJames

24

Ще одна річ, про яку слід пам’ятати, полягає в наступному… Якщо не перевіряти сторону сервера ваших бізнес-правил, це означає, що ви невірно довіряєте тому, що потрапляє, скажімо, на запит POST, є дійсним.

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

Тож моя пропозиція полягає в тому, щоб перенести ваші бізнес-правила до API, нехай він перевіряє введення та повертає відповідні помилки (або, можливо, просто коди, що вказують, що пішло не так) в тілі відповіді. Ці коди можуть бути використані вашим додатком, щоб вказати, що пішло не так.


5
На сьогодні це найбільш корисна відповідь: API - це атакова поверхня, а не вхід для клієнта. Будь-який запит API може бути підроблений. Таким чином, все, що можна зробити за допомогою чистого API - це те, що може зробити талантливий, злісний малюк сценарію. Клієнтське програмне забезпечення може бути використане для кращого користувацького досвіду, але саме цей сервер повинен виконувати правила.
cmaster

10

Тут можна додати інші відповіді:

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

Однією з головних переваг використання сервісів є те, що деталі впровадження можуть бути змінені, не вимагаючи від клієнтів нічого. З того, що ви описали, це здається, що немає реального шару абстракції. Деталі реалізації були розкриті через HTTP. Нічого про REST не говорить про те, що потрібно, корисно чи бажано. Насправді, я думаю, я міг би стверджувати, що певні частини визначення REST означають, що це насправді нереалізована реалізація.

Що ви пропонуєте - це як правильно розробити належний рівень обслуговування. Якщо хтось каже вам, що ви не можете цього зробити, тому що це не RESTful, це прикро. Ви можете бути впевнені, що той, хто вам каже, що мало що знає про REST.

Виходячи з вашого запитання, у вас є ресурс, званий клієнт. Все і все, що потрібно для створення дійсного клієнтського ресурсу, можна і потрібно обробляти в POSTресурсі бази клієнтів (або по черзі / необов'язково в PUT до певного ресурсу клієнта, якщо його не існує.) REST нічого не говорить про те, скільки записи баз даних, які потрібно створити під час даного дзвінка. Як зауважив Колін Янг, взагалі не потрібно мати базу даних, це абсолютно не має значення, як служби реалізуються з точки зору REST.


3
REST нічого не говорить про записи бази даних, не кажучи вже про кількість. Я міг би створити службу REST, яка контролювала клапан води та відкривала клапан води, водопровід та резервуари. Ви можете стверджувати, що самі фізичні об'єкти - це "база даних", але це трохи розтягує речі.
Колін Янг

@ColinYoung Так, дякую за допомогу в уточненні.
JimmyJames

3

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

REST не в тому, щоб переконатися, що ваш API дозволяє зберігати та отримувати дані. Скоріше, це стосується моделювання дій як ресурсів. Ваш API повинен дозволяти вживати дій ( зрештою, це інтерфейс програмування додатків). Питання в тому, як моделювати ці дії.

Замість того, щоб придумати термін, приклади, мабуть, є найкращим способом пояснити це своїм колегам . Таким чином ви можете показати, як вони це роблять зараз, які проблеми це спричиняє, рішення, яке вирішує проблему, і як вона все ще залишається RESTful.

Давайте подивимось на ваш об’єкт Клієнта.

Проблема:

Користувальницький інтерфейс розміщує Клієнта, але наступні таблиці ще не були оновлені. Що робити, якщо один із наступних дзвінків не вдасться через помилку у вашому коді користувальницького інтерфейсу (або неправильно працює плагін браузера тощо)? Тепер ваші дані перебувають у несуперечливому стані. Це навіть може бути стан, який порушує інші частини вашого API чи інтерфейсу користувача, не кажучи вже про те, що він просто недійсний. Як ви одужуєте? Вам доведеться перевірити кожен можливий стан, щоб бути впевненим, що це щось не порушить, але важко буде знати, що можливо.

Рішення:

Створіть кінцеву точку API для створення клієнтів. Ви знаєте, що не хочете мати кінцеву точку "/ customer / create" або навіть "/ create-customer", оскільки create є дієсловом і порушує REST. Тож іменуйте це. "/ створення клієнтів" може працювати. Тепер, коли ви розмістите об’єкт CustomerCreation, він надішле всі необхідні поля, щоб клієнт був повністю створений. Кінцева точка гарантує, що дані будуть повноцінними та дійсними (повернення 400 або щось інше, якщо не вдалося перевірити), і може зберігатись, наприклад, у межах однієї db транзакції.

Якщо вам також потрібна кінцева точка для об’єктів GET / клієнт, це добре. Ви можете мати і те, і інше. Хитрість полягає у створенні кінцевих точок, які обслуговують потреби споживачів.

Переваги:

  1. Ви гарантуєте, що у вас не буде поганого стану
  2. На дисках інтерфейсу користувача насправді простіше, якщо їм не доведеться «знати» впорядкування запитів, проблеми з підтвердженням тощо
  3. Це не так балакуче API, скорочуючи затримку мережевих запитів
  4. Простіше тестувати та концептуалізувати сценарії (відсутні / неправильно сформовані фрагменти даних із інтерфейсу користувача не поширюються між запитами, деякі з яких можуть не працювати)
  5. Це дозволяє краще вкладати бізнес-логіку
  6. Як правило, безпека полегшується (тому що логіку бізнесу та оркестрування в інтерфейсі можуть змінювати користувачі)
  7. Це, ймовірно, зменшить дублювання логіки (швидше за все, ви матимете 2+ споживачів API, ніж 2+ API, які надають доступ до тих же даних)
  8. Ще 100% ВІДПОВІДНО

Недоліки:

  1. Це може бути більше роботи для бек-енд-дев (але може бути не в довгостроковій перспективі)

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

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

Подальше навчання:

Ця стаття з роздумів дійсно допомогла мені зрозуміти, як моделювати дії як об’єкти, використовуючи практичні приклади: https://www.thoughtworks.com/insights/blog/rest-api-design-resource-modeling

Я б також запропонував прочитати на CQRS та події Sourcing, оскільки вони стосуються саме подібних речей (тобто розлучення вашого API від фактичної логіки збереження). Я не знаю, наскільки готові ваші колеги будуть читати подібні речі, але це може дати вам більше ясності та допоможе вам пояснити їх.


" тому що create є дієсловом і порушує REST " - Абсолютно правильно. Іншими словами, це був би 47.258.346-й підхід для запуску " RPC over REST ". Що б я хоч би пояснило як "неприродне", оскільки воно зловживає та неправильно представляє підходи RESTful (у них є випадки їх використання, але RPC не є одним з них), а також, як правило, є неефективним.
JensG
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.