Предупреждение: большой пост, некоторые мнения, расплывчатое заключение «делай, что лучше для тебя»
Как правило, это делается как средство реализации «шестиугольной архитектуры» вокруг вашей базы данных. У вас могут быть веб-приложения, мобильные приложения, настольные приложения, оптовые импортеры и фоновая обработка - все они используют вашу базу данных единообразно. Конечно, вы могли бы сделать то же самое в некоторой степени, написав богатую библиотеку для доступа к вашей базе данных, и чтобы все ваши процессы использовали эту библиотеку. И действительно, если вы находитесь в небольшом магазине с очень простой системой, это, вероятно, лучший путь; Это более простой подход, и если вам не нужны расширенные возможности более сложной системы, зачем платить за сложность? Однако, если вы работаете с большим, сложным набором систем, которые все должны взаимодействовать с вашей базой данных в масштабе,
Независимость и обслуживание платформы
Если у вас есть база данных, и вы пишете библиотеку 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