почему люди делают REST API вместо DBAL?


32

В прошлых двух компаниях, в которых я работал в REST API, существовал запрос данных через веб-приложение. то есть. вместо того, чтобы веб-приложение выполняло SQL напрямую, оно вызывает REST API, которое выполняет SQL и возвращает результат.

Мой вопрос ... почему это сделано?

Если бы это собиралось быть выставленным третьим лицам, я мог понять. Лучше выставить ограниченный REST API, чем полную БД. Но в обеих этих компаниях дело обстоит иначе.

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

В любом случае это кажется ненужным для меня. И я думаю, что это также затрудняет диагностику проблем. Если в отчете в веб-приложении указаны неправильные номера, вы не можете просто вывести SQL-запрос - вам нужно сбросить URL-адрес REST, а затем перейти в проект, который служит в качестве REST API, и извлечь из него SQL-запрос. Так что это дополнительный уровень косвенности, который замедляет процесс диагностики.


3
Похоже, вы работали только с приложениями, которые в основном CRUD - некоторые пользователи вводят данные с помощью форм, а другие читают данные с помощью тех же форм или с распечатками отчетов? Если вы никогда не работали с системой, в которой требуется сложная и изощренная модель предметной области, тогда я могу понять, как у вас складывается такое мышление. Многим приложениям требуется дополнительный уровень косвенности для выполнения каких-либо задач.
Рибальд Эдди

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

1
В REST API есть свои особенности, которые мешают хорошо спроектировать сложный домен - большинство разработчиков, с которыми я встречался годами, не заботятся о дизайне. Они хотят набрать код как можно быстрее, чтобы их начальники полюбили их и подумали, что они рок-звезды. Когда вы объединяете этот факт с таким трендом, как REST, вы получаете модный, но непрактичный API для спагетти. Это не имеет никакого отношения к самому REST.
Рибальд Эдди

3
Вы когда-нибудь задумывались, как некоторые веб-компании сообщают, что их пользовательские записи были украдены хакером? Вы никогда не задумывались, как хакер это сделал? Когда вы думаете, что веб-сервер имеет прямое соединение с БД, вы понимаете, что после взлома веб-сервера у злоумышленника есть полный и неограниченный доступ к выбору чего-либо из БД, которая ему нравится. Поместите его за средний уровень, и тогда атакующий может вызывать только методы среднего уровня. Я не скажу, что это мгновенная безопасность, но она значительно лучше.
gbjbaanb

1
@gbjbaanb: Моя точка зрения заключается в том, что веб-сервер может получить доступ к данным через остальной сервер, поэтому, если веб-сервер взломан, злоумышленник также может получить доступ к данным через остальной сервер без необходимости взлома остального сервера.
JacquesB

Ответы:


28

Если вы разрешите клиенту напрямую обращаться к базе данных - что он будет делать, даже с уровнем абстракции базы данных, то:

  • Вы получаете связь между их кодом и вашим - в частности, существует очень сильная связь между структурой вашей базы данных и их кодом;
  • Ваш клиент может сделать некоторые довольно нежелательные вещи в вашей базе данных - будь то обновление данных, которые они не должны делать, написание запроса, который занимает слишком много времени, блокировка чего-либо, потому что они не получают блокировки чисто ...
  • Если вы сделали какой-то неоптимальный выбор в своей структуре базы данных, переход от этого выбора может быть очень трудным, особенно если у вас нет хорошего способа заставить ваших клиентов перейти на новые структуры.

То есть я совсем не касаюсь части REST - изоляция вашей базы данных через API - это просто более разумный выбор, если команда, которая поддерживает базу данных, и команды, которые ее используют, не синхронизированы, поскольку это позволяет этим частям развиваться в своем собственном темпе.


24

Вы правы, нет явного преимущества, связанного с внедрением уровня API REST между веб-приложением и базой данных, и это сопряжено с затратами на сложность и снижение производительности.

Причиной того, что вы получаете противоречивые ответы, является путаница в том, что является «клиентом» в вашей архитектуре.

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

Но есть некоторые другие архитектуры, где REST API имеет смысл:

  • Если у вас есть несколько клиентов, обращающихся к базе данных, то есть не одно веб-приложение, а несколько независимых веб-приложений, обращающихся к одной и той же базе данных. Может быть полезно создать общий интерфейс REST, чтобы разрешить совместное использование модели данных, кэширования и т. Д. Конечно, вы можете получить некоторые преимущества, используя одни и те же библиотеки DAL, но это не сработает, если приложения разрабатываются на разных языках и на разных платформ. Это распространено в корпоративных системах.

  • Если у вас есть несколько настольных приложений, которые обращаются к базе данных напрямую. Это классическая «двухуровневая» архитектура, которая потеряла популярность по сравнению с веб-приложениями. Введение уровня REST позволяет централизовать логику доступа к данным и, в особенности, обеспечивает более жесткий контроль безопасности, поскольку рискованно иметь несколько распределенных клиентов, напрямую обращающихся к одной и той же базе данных.

  • Если у вас есть код JavaScript, который напрямую извлекает данные с сервера, то в любом случае вам понадобится что-то вроде REST API.


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

@satich: Я не совсем понимаю, что вы спрашиваете, вы можете быть более конкретным? Вы спрашиваете об одной точке отказа с или без уровня REST?
JacquesB

Дополнительный слой может быть полезен, если с ним
связано

@ Иван: Да, это то, что я заявляю в первом пункте пули.
JacquesB

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

12

Предупреждение: большой пост, некоторые мнения, расплывчатое заключение «делай, что лучше для тебя»

Как правило, это делается как средство реализации «шестиугольной архитектуры» вокруг вашей базы данных. У вас могут быть веб-приложения, мобильные приложения, настольные приложения, оптовые импортеры и фоновая обработка - все они используют вашу базу данных единообразно. Конечно, вы могли бы сделать то же самое в некоторой степени, написав богатую библиотеку для доступа к вашей базе данных, и чтобы все ваши процессы использовали эту библиотеку. И действительно, если вы находитесь в небольшом магазине с очень простой системой, это, вероятно, лучший путь; Это более простой подход, и если вам не нужны расширенные возможности более сложной системы, зачем платить за сложность? Однако, если вы работаете с большим, сложным набором систем, которые все должны взаимодействовать с вашей базой данных в масштабе,

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

Если у вас есть база данных, и вы пишете библиотеку Python для взаимодействия с этой базой данных, и каждый использует эту библиотеку для взаимодействия с базой данных, это здорово. Но, скажем, вдруг вам нужно написать мобильное приложение, и теперь это мобильное приложение должно также взаимодействовать с базой данных. И ваши инженеры iOS не используют Python, а ваши инженеры Android не используют Python. Возможно, ребята из iOS хотят использовать языки Apple, а инженеры Android хотят использовать Java. Тогда вы застряли бы в написании и поддержке вашей библиотеки доступа к данным на 3 разных языках. Возможно, разработчики iOS и Android решили использовать что-то вроде Xamarin, чтобы максимизировать код, которым они могут поделиться. Отлично, за исключением того, что вам, вероятно, все еще придется портировать вашу библиотеку доступа к данным на .NET. А потом ваша компания только что купила другую компанию, которая Веб-приложение является разрозненным, но связанным продуктом, и бизнес хочет интегрировать некоторые данные с платформы вашей компании в платформу недавно приобретенной дочерней компании. Есть только одна проблема: дочерняя компания была стартапом и решила написать основную часть своего приложения в Dart. Кроме того, по каким-либо причинам (возможно, по независящим от вас причинам) мобильная команда, которая пилотировала Xamarin, решила, что это не для них, и что они предпочитают использовать инструменты и языки, специфичные для мобильных устройств, для которых они будут разрабатывать. Но пока вы были на этом этапе, ваша команда уже поставила большую часть вашей библиотеки доступа к данным в .NET, а другая команда в компании писала несколько сумасшедших вопросов интеграции с Salesforce и решила сделать все это в .NET, так как была уже библиотека доступа к данным для.

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

Пожалуйста, поймите, что в некоторых средах приведенный выше пример совсем не надуман. Также примите во внимание, что эта последовательность событий может разворачиваться в течение нескольких лет. Как правило, когда вы подходите к тому моменту, когда архитекторы и бизнесмены начинают говорить о подключении других систем к вашей базе данных, именно тогда вы захотите включить «REST API перед базой данных» в свою дорожную карту. Подумайте, если раньше, когда стало ясно, что эта база данных начнет совместно использоваться несколькими системами, перед ней был поставлен API веб-службы / REST. Исправление вашей ошибки валидации будет намного быстрее и проще, потому что вы делаете это один раз, а не 5 раз. И выпустить исправление было бы намного проще, потому что вы

TLDR; Проще централизовать логику доступа к данным и поддерживать очень тонких клиентов HTTP, чем распределять логику доступа к данным для каждого приложения, которому необходим доступ к данным. На самом деле ваш HTTP-клиент может быть даже сгенерирован из метаданных. В больших системах REST API позволяет поддерживать меньше кода

Производительность и масштабируемость

Некоторые люди могут полагать, что разговор с базой данных напрямую, а не через веб-сервис сначала быстрее. Если у вас есть только одно приложение, это, безусловно, правда. Но в больших системах я не согласен с мнением. В конечном счете, на каком-то уровне масштабирования будет очень полезно поместить какой-то кеш перед базой данных. Возможно, вы используете Hibernate и хотите установить сетку Infinispan в качестве кэша L2. Если у вас есть кластер из 4 мощных серверов для размещения вашего веб-сервиса отдельно от ваших приложений, вы можете позволить себе иметь встроенную топологию с включенной синхронной репликацией. Если вы попытаетесь поместить это в кластер из 30 серверов приложений, издержки на включение репликации в этой настройке будут слишком большими, поэтому вы ' Вам придется либо запускать Infinispan в распределенном режиме, либо в какой-то выделенной топологии, и внезапно Hibernate должен выйти из сети для чтения из кэша. Кроме того, Infinispan работает только на Java. Если у вас есть другие языки, вам понадобятся другие решения для кэширования. Сетевые накладные расходы, связанные с необходимостью перехода от приложения к веб-службе до достижения базы данных, быстро компенсируются необходимостью использовать гораздо более сложные решения для кэширования, которые, как правило, идут самостоятельно.

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

Вдобавок ко всему, наличие множества клиентов, направленных на вашу базу данных, вместо того, чтобы указывать на несколько серверов, которые в свою очередь указывают на базу данных, может значительно усложнить настройку базы данных и пула соединений. В целом, большая часть фактической рабочей нагрузки на сервере приложений - это приложения; ожидание возвращения данных из базы данных часто отнимает много времени, но обычно не требует больших вычислительных затрат. Вам может понадобиться 40 серверов для обработки рабочей нагрузки вашего приложения, но вам, вероятно, не нужно 40 серверов для организации извлечения данных из базы данных. Если вы посвятите эту задачу веб-службе, веб-служба, вероятно, будет работать на гораздо меньшем количестве серверов, чем остальная часть приложения, что означает, что вам потребуется гораздо меньше подключений к базе данных. Что важно, потому что базы данных обычно не

TLDR; Настраивать, масштабировать и кэшировать доступ к данным проще, когда это происходит внутри одного выделенного веб-сервиса, чем когда это происходит во многих различных приложениях с использованием разных языков и технологий.

Последние мысли

Пожалуйста, не отказывайтесь от мысли: «Ого, я всегда должен использовать API REST для получения моих данных» или «Этот идиот пытается сказать, что мы делаем это неправильно, потому что наше веб-приложение напрямую обращается к базе данных, но наши вещи работают отлично! , Главное, что я пытаюсь сделать, это то, что разные системы и разные компании предъявляют разные требования; Во многих случаях размещение REST API перед вашей базой данных действительно не имеет смысла. Это более сложная архитектура, которая требует обоснования этой сложности. Но когда сложность оправдана, использование REST API дает массу преимуществ. Способность взвесить различные проблемы и выбрать правильный подход для вашей системы - вот что делает хорошего инженера.

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

Источники: http://alistair.cockburn.us/Hexagonal+architecture https://github.com/brettwooldridge/HikariCP/wiki/About-Pool-Sizing


Очень хороший ответ, стоит прочитать. Спасибо, что нашли время, чтобы написать этот отличный ответ!
Доминик

6

Если я правильно понимаю, что такое DBAL , то ответ таков: интерфейс REST позволяет вам использовать любой язык для своих клиентов, тогда как DBAL - это библиотека, которая позволяет вам использовать один язык для своих клиентов.

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

В более абстрактных терминах вы сами отвечаете на вопрос:

Так что это дополнительный уровень косвенности, который замедляет процесс диагностики

... так как существует этот знаменитый афоризм, который гласит: «Все проблемы в информатике могут быть решены с помощью другого уровня косвенности». :)


6

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

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


3

Вы думаете, что REST для запросов к базе данных, и это не так. ОТДЫХ представляет состояние чего-либо в данный момент. Использование REST изменяет или возвращает представление, но это все. Если это состояние становится доступным для базы данных, это не имеет значения и никого не волнует, потому что КАК это представление не является частью REST и не является запросом к базе данных.


Я не предполагаю, что запросы к базе данных == REST. Конечно, REST способен быть гораздо большим, чем уровень абстракции базы данных, но в последних двух компаниях, над которыми я работал, это, по сути, все, чем он является - уровень абстракции базы данных. Он не делает ничего другого , чем переводить HTTP запросы на запросы БД. И если это все, что вы делаете, мне кажется, что вам лучше обслужит DBAL. Действительно, мне кажется, что единственная причина, по которой некоторые люди используют REST в наши дни, заключается в том, что это модно, а не потому, что это лучшее решение для стоящей перед нами задачи.
Нойберт

@neubert Работает ли DBAL напрямую через Интернет, как REST?
Роб

Конечно. Вы можете указать MySQL использовать IP-адрес / имя домена / порт, который принадлежит другому компьютеру в Интернете. Вы можете использовать SSH туннелирование, а также (я считаю) аутентификацию SSL. Предположительно другие СУБД работают аналогично.
Нойберт

@neubert: в этом случае REST API - это 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.