чому люди роблять API REST замість DBAL?


32

У двох останніх компаніях, в яких я був у REST API, існує запит даних через веб-додаток. тобто. замість того, щоб веб-додаток робити SQL безпосередньо, він викликає API REST, і це робить SQL і повертає результат.

Моє запитання: чому це робиться?

Якщо це буде піддаватися стороннім сторонам, я б міг зрозуміти. Краще виставити обмежений API REST, ніж повний БД. Але в обох цих компаніях це не так.

Мені було запропоновано, що ці API REST полегшують перехід між СУБД. Але чи не в цьому полягає рівень шару абстрагування бази даних (DBAL)? Можливо, ви використовуєте ORM як свій DBAL або, можливо, ви можете просто написати необроблений SQL і змусити DBAL перекласти конкретні речі DB, якщо це доречно (наприклад, перекладіть LIMIT для MySQL в TOP для MSSQL).

Так чи інакше мені це здається непотрібним. І я думаю, що це також ускладнює діагностику проблем. Якщо звіт про веб-додаток дає неправильні цифри, ви не можете просто скинути SQL-запит - вам потрібно скинути REST URL-адресу, а потім перейти до проекту, який служить API REST і витягнути з нього SQL. Тож це зайвий шар непрямості, який уповільнює діагностичний процес.


3
Здається, ви працювали лише з додатками, які в основному є CRUD - деякі користувачі вводять дані у форми, а інші користувачі читають дані тими самими формами або з роздруківками звітів? Якщо ви ніколи не працювали із системою, яка потребує складної та складної моделі домену, то я можу побачити, як у вас би виникло саме таке мислення. У багатьох програмах потрібен додатковий шар непрямості, щоб виконувати завдання.
RibaldEddie

1
Я працював з API (не обов’язково REST), який (серед іншого) виконував обчислення параметрів, які були передані йому. Можливо, у цих розрахунках використовується СУБД, але, мабуть, багато базується на логіці в БД. Однак внутрішні API в компаніях, в яких я працював, цього не роблять. Вони просто запитують СУБД і виписують результати дослівного запиту SQL. Мені просто здається, що API REST часто (не завжди - часто) пишуться модно - не бути практичним.
Нейберт

1
Однозначно вигадки щодо дизайну API REST, які ускладнюють добре спроектувати складний домен. Більшість розробників, з якими я зустрічався протягом багатьох років, не цікавляться дизайном. Вони хочуть якнайшвидше викрити код, щоб їх начальство полюбило їх і подумало, що вони рок-зірки. Поєднуючи цей факт з такою тенденцією, як REST, ви отримуєте модний, але непрактичний API спагетті. Це не має нічого спільного з самим REST.
RibaldEddie

3
коли-небудь цікаво, як деякі веб-компанії повідомляють, що цілі записи користувачів були вкрадені хакером? Ніколи не замислювалися, як це зробив хакер? Якщо ви думаєте, що веб-сервер має пряме з'єднання з БД, ви розумієте, щойно веб-сервер зламаний, зловмисник має повний і необмежений доступ, щоб вибрати що-небудь з БД, який йому подобається. Дотримуйтесь його за середнім рівнем, і зловмисник може лише викликати методи середнього рівня. Я не скажу, що це моментальна безпека, але її значно краще.
gbjbaanb

1
@gbjbaanb: Моя думка полягає в тому, що веб-сервер може отримати доступ до даних через сервер відпочинку, тому, якщо веб-сервер зламаний, зловмисник також може отримати доступ до даних через сервер відпочинку, без злому сервера відпочинку.
ЖакБ

Відповіді:


28

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

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

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


24

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

Причина, коли ви отримуєте суперечливі відповіді, - це плутанина щодо того, що є «клієнтом» у вашій архітектурі.

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

Але є деякі інші архітектури, де REST API має сенс:

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

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

  • Якщо у вас є код JavaScript, який безпосередньо отримує дані з сервера, тоді вам потрібно щось на зразок REST API.


1
Мені сподобалась ваша відповідь, але у мене є ще кілька запитів, які поставляються з нею. Як, як щодо втрати продуктивності із впровадженням іншого шару абстракції? Крім того, це не робить єдину точку відмови (якщо це знижується, все інше знижується) і можливе вузьке місце (кожен додаток, що чекає на з'єднання БД з пулом)?
сатрій

@satich: Я не розумію, про що ви питаєте, чи можете ви бути більш конкретними? Ви запитуєте про одноосібний збій із рівнем REST або без нього?
ЖакB

Додатковий шар може мати користь, якщо з ним спілкується більше одного додатка
Ewan

@Ewan: Так, це я констатую в першій точці кулі.
ЖакБ

1
@JacquesB Припустимо, що декілька веб-додатків діляться одними і тими ж БД, але не однаковими даними, тобто кожен, що робить операції CRUD над окремим набором даних у цій БД, в основному немає спільного використання даних у справжньому сенсі. Так чи має сенс розміщувати програми за рамками спокійної стійкості (також припускаємо, що БД забезпечує хороший рівень одночасності запитів)? Більше того, чи не буде ця структура вузьким місцем, а також єдиною точкою відмови для багатьох веб-додатків, що взаємодіють через неї?
Сактив

12

Попередження: велика публікація, деякі думки, невизначені "роби те, що найкраще підходить для тебе"

Як правило, це робиться як засіб реалізації «шестикутної архітектури» навколо вашої бази даних. Ви можете мати веб-додатки, мобільні додатки, настільні додатки, масові імпортери та обробку фонових даних, всі споживають вашу базу даних рівномірно. Звичайно, ви могли певною мірою зробити те саме, написавши багату бібліотеку для доступу до вашої бази даних, і всі ваші процеси використовують цю бібліотеку. І справді, якщо ви перебуваєте в невеликому магазині з дуже простою системою, це, мабуть, кращий шлях; Це простіший підхід, і якщо вам не потрібні розширені можливості більш складної системи, навіщо платити за складність? Однак якщо ви працюєте з великим, вдосконаленим набором систем, які всі потребують взаємодії з вашою базою даних в масштабі,

Незалежність та обслуговування платформи

Якщо у вас є база даних, і ви пишете бібліотеку Python для взаємодії з цією базою даних, і всі тягнуть її в цю бібліотеку для взаємодії з базою даних, це чудово. Але, скажімо, раптом вам потрібно написати мобільний додаток, і тепер цей мобільний додаток повинен поговорити з базою даних. І ваші інженери iOS не використовують Python, а ваші Android-інженери не використовують Python. Можливо, хлопці з iOS хочуть використовувати мови Apple, а інженери Android хочуть використовувати Java. Тоді ви застрягли б у написанні та підтримці бібліотеки доступу до даних трьома різними мовами. Можливо, розробники iOS та Android вирішили використовувати щось на кшталт Xamarin, щоб максимально використовувати код, яким вони можуть ділитися. Ідеально, за винятком того, що вам, мабуть, все ж доведеться перенести бібліотеку доступу до даних до .NET. І тоді ваша компанія щойно придбала іншу компанію, яка Веб-додаток s - це розрізнений, але пов’язаний із цим продукт, і бізнес хоче інтегрувати деякі дані з платформи вашої компанії в платформу нещодавно придбаного дочірнього підприємства. Тільки є одна проблема: дочірня компанія була стартапом і вирішила написати основну частину своєї заявки в Dart. Крім того, з будь-яких причин (напевно, поза вашим контролем) мобільна команда, яка пілотувала Xamarin, вирішила, що це не для них, і вони скоріше використовуватимуть інструменти та мови, характерні для мобільних пристроїв, для яких вони розроблять. Але поки ви були на цій фазі, ваша команда вже доставила значну частину вашої бібліотеки доступу до даних у .NET, а інша команда компанії написала деякі шалені речі з інтеграції Salesforce і вирішила зробити все це в .NET, оскільки там вже була бібліотекою доступу до даних для.

Отже, через дуже реалістичний поворот подій у вас є бібліотека доступу до даних, написана в Python, .NET, Swift, Java та Dart. Вони не такі приємні, як ви хотіли б, щоб вони були. Ви не можете використовувати ORM так ефективно, як хотіли б, оскільки кожна мова має різні засоби ORM, тому вам довелося написати більше коду, ніж хотілося б. І ви не змогли приділити стільки часу кожному втіленню, як хотіли б, бо їх 5. А версія Dart бібліотеки особливо волохата, тому що вам довелося передавати свої власні трансакційні речі для частини цього, оскільки бібліотеки та підтримка просто не були там. Ви намагалися зробити так, що через це програма Dart повинна мати функціонал лише для читання для вашої бази даних, але бізнес вже вирішив, що будь-які функції, які вони планували, варті додаткових зусиль. І виявляється, є помилка в деякій логіці перевірки, яка існує у всіх цих втіленнях вашої бібліотеки доступу до даних. Тепер вам потрібно написати тести та код, щоб виправити цю помилку у всіх цих бібліотеках, отримати огляди коду на зміни, що внесені до всіх цих бібліотек, отримати QA для всіх цих бібліотек та випустити ваші зміни до всіх систем, використовуючи всі ці бібліотеки. Тим часом ваші клієнти незадоволені і розпочали роботу в Twitter, поєднуючи в собі поєднання вульгарностей, які ви ніколи не могли б уявити, що можна було б задумати, не кажучи вже про націлену на флагманський продукт вашої компанії. А власник продукту вирішує взагалі не дуже розуміти ситуацію.

Будь ласка, розумійте, що в деяких середовищах наведений вище приклад є лише надуманим. Також врахуйте, що ця послідовність подій може розгортатися протягом кількох років. Як правило, коли ви добираєтесь до того, що архітектори та ділові люди починають говорити про підключення інших систем до вашої бази даних, саме тоді вам потрібно буде "поставити API REST перед базою даних" на свою дорожню карту. Подумайте, якщо на початку, коли було зрозуміло, що дана база даних почне розповсюджуватися кількома системами, перед нею буде розміщений веб-сервіс / REST API. Виправити помилку перевірки було б набагато швидше та простіше, оскільки ви робите це один раз, а не 5 разів. І випустити виправлення було б набагато простіше скоординуватись, тому що ви

TLDR; Простіше централізувати логіку доступу до даних та підтримувати дуже тонких клієнтів HTTP, ніж розповсюджувати логіку доступу до даних для кожної програми, якій потрібно отримати доступ до даних. Насправді ваш HTTP-клієнт може навіть генеруватися з метаданих. У великих системах API REST дозволяє зберігати менше коду

Продуктивність та масштабованість

Деякі люди можуть вірити, що спілкування з базою даних безпосередньо замість того, щоб спочатку пройти веб-сервіс, відбувається швидше. Якщо у вас є лише одна заявка, це, безумовно, так. Але у більших системах я не згоден з настроями. Врешті-решт, на певному рівні масштабів буде дуже вигідно розмістити якийсь кеш перед базою даних. Можливо, ви використовуєте Hibernate і хочете встановити Infinispan сітку як кеш L2. Якщо у вас є кластер із чотирьох надійних серверів для розміщення вашої веб-служби окремо від ваших програм, ви можете дозволити собі вбудовану топологію із синхронною реплікацією. Якщо ви спробуєте помістити це на кластер із 30 серверів прикладних програм, витрати на включення реплікації в цій програмі будуть занадто великими, тож ви ' Вам доведеться або запустити Infinispan в розподіленому режимі, або в якомусь виділеному топології, і раптом Hibernate повинен вийти через мережу, щоб прочитати з кеша. Крім того, Infinispan працює лише на Java. Якщо у вас є інші мови, вам знадобляться інші рішення кешування. Мережеві накладні витрати на перехід від вашої програми до вашого веб-сервісу до досягнення бази даних швидко компенсуються необхідністю використання набагато складніших кешових рішень, які, як правило, мають власні накладні витрати.

Крім того, цей рівень HTTP вашого API REST забезпечує ще один цінний механізм кешування. Ваші сервери для вашого REST API можуть розміщувати заголовки кешування на їх відповіді, і ці відповіді можуть кешуватися на мережевому шарі, який масштабує надзвичайно добре. У невеликих налаштуваннях з одним або двома серверами найкраще використовувати просто кеш пам'яті в програмі, коли він спілкується з базою даних, але у великій платформі з багатьма програмами, що працюють на багатьох серверах, ви хочете використовувати мережа для кешування кешування, тому що при правильній настройці щось на зразок кальмарів чи лаку чи nginx може наблизитись до божевільних рівнів порівняно невеликого обладнання. Сотні тисяч або мільйонів запитів в секунду пропускної здатності набагато дешевше зробити з кеша HTTP, ніж з сервера прикладних програм або бази даних.

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

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

Заключні думки

Будь ласка, не відволікайтесь від цього думки: "О, о, я завжди повинен використовувати API REST для отримання своїх даних" або "Цей ідіот намагається сказати, що ми робимо це неправильно, оскільки наш веб-додаток безпосередньо спілкується з базою даних, але наші речі чудово працюють! " . Основний момент, який я намагаюся зробити, - це те, що різні системи та різні підприємства мають різні вимоги; У багатьох випадках ставити API REST перед вашою базою даних насправді не має сенсу. Це більш складна архітектура, яка вимагає виправдання цієї складності. Але коли складність виправдана, є тонна перевага від наявності REST API. Можливість зважити різні проблеми та вибрати правильний підхід для вашої системи - це те, що робить хорошого інженера.

Крім того, якщо API REST перешкоджає налагодженню речей, на цій картині, ймовірно, щось не так або відсутнє. Я не вірю, що додавання шару абстракції суттєво ускладнює налагодження. Коли я працюю з великими, n-ярусними системами, мені подобається переконатися, що я маю контекст розподіленого журналу. Можливо, коли користувач ініціює запит, згенеруйте GUID для цього запиту та введіть ім’я користувача цього користувача та запит, який він зробив. Потім передайте цей GUID, коли ваша програма переговорить з іншими системами. Завдяки правильній агрегації та індексації журналів, ви можете запитувати всю свою платформу для користувача, який повідомляє про проблему, і мати видимість у всіх своїх діях, і вони проскакують через систему, щоб швидко визначити, де все пішло не так. Знову ж таки, це більш складна архітектура,

Джерела: http://alistair.cockburn.us/Hexagonal+architecture https://github.com/brettwooldridge/HikariCP/wiki/ About-Pool- Sizing


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

6

Якщо я правильно розумію, що таке DBAL , то відповідь полягає в тому, що інтерфейс REST дозволяє використовувати будь-яку мову для своїх клієнтів, тоді як DBAL - це бібліотека, яка дозволяє використовувати одну мову для своїх клієнтів.

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

Більш абстрактно, ви самі відповідаєте на питання:

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

... оскільки існує цей відомий афоризм, який говорить: "Усі проблеми в інформатиці можна вирішити іншим рівнем непрямості". :)


6

Тільки тому, що ви всередині однієї компанії, не означає, що ви повинні виставляти все для всіх. API REST - це спосіб визначити обмежений зв'язок споживача / постачальника між командами в компанії, з чітким договором. Amazon став першопрохідцем у цій формі організації.

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


3

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


Я не припускаю, що запити до бази даних == REST. Безумовно, REST здатний бути набагато більшим, ніж рівень абстрагування бази даних, але в останніх двох компаніях, над якими я працював, це по суті все, що це - рівень абстракції бази даних. Він не робить нічого іншого , ніж переводити HTTP запити на запити БД. І якщо це все, що ви робите, мені здається, вам краще послужиться DBAL. Дійсно, мені здається, що єдиною причиною, коли деякі люди сьогодні використовують REST, є те, що це модно - не тому, що це найкраще рішення для вирішення поставлених завдань.
Нейберт

@neubert чи працює DBAL безпосередньо через Інтернет, як REST?
Роб-

Звичайно. Ви можете сказати MySQL використовувати IP-адресу / доменне ім’я / порт, який належить іншому комп'ютеру в Інтернеті. Ви можете використовувати SSH тунелювання, а також (я вважаю) SSL auth також. Імовірно, аналогічні роботи інших СУБД.
Нейберт

@neubert: у такому випадку API REST - це DBAL, чи не так?
RemcoGerlich

2
@RemcoGerlich - впевнено, але використовуючи REST API як DBAL, можливо, ви додаєте середній шар, який є непотрібним і перешкоджає діагностиці проблем. Я маю на увазі, якщо ви будете використовувати досить широке визначення DBAL, тоді ви можете вважати, що Google SERP є DBAL. Вам просто потрібно проаналізувати HTML, щоб отримати пакульовані дані з серверів Google ...
neubert
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.