Как структурировать бэкэнд API RESTful с базой данных? - PullRequest
0 голосов
/ 09 июня 2019

Я хочу создать API, использующий REST, который взаимодействует (хранит) данные в базе данных.

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

Вот пример

И все же у меня есть два вопроса:

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

  • Имея все это в виду, и, в моем случае, используяgolang, как проект должен быть структурирован с точки зрения файлов и функций?

    • У меня будет основной файл со всеми конечными точками из REST API, вызывающий контроллеры, которые обрабатывают эти запросы.
    • У меня будет набор файлов, которые определяют эти контроллеры.Являются ли эти контроллеры удаленным фасадом?Должны ли эти методы не иметь логики в этом случае и просто вызывать эквивалентные локальные методы?
    • Должны ли локальные методы вызывать базу данных напрямую или они должны использовать какой-то вспомогательный класс, который обращается к базе данных?

Если все вопросы положительные, имеет ли смысл следующая структура?

  • Main
  • Контроллеры
  • Домен
  • Помощник по базе данных

1 Ответ

0 голосов
/ 09 июня 2019

Прежде всего, как заявил Майк Амундсен

Ваша модель данных - это не ваша объектная модель, это не ваша модель ресурсов, а не ваша модель обеспечения

Джим Уэббер сказал что-то очень похожее , что, реализуя архитектуру REST, вы получаете интеграционную модель в виде Web, которая управляется HTTP, а другая является моделью домена. Ресурсы адептируют и проецируют вашу модель предметной области на весь мир, хотя нет никакого соотношения 1: 1 между данными в вашей базе данных и представлениями, которые вы отправляете. Типичная система REST имеет гораздо больше ресурсов, чем записи БД в модели вашего домена.

С учетом вышесказанного трудно дать конкретный совет о том, как вы должны структурировать свой проект, особенно с точки зрения определенной структуры, которую вы хотите использовать. Что касается Роберта "Дядя Боб" К. Мартина, который рассматривает структуру кода, он должен рассказать вам о намерениях приложения, а не об используемой вами инфраструктуре ¹ . По его словам Архитектура имеет намерение . Хотя обычно вы видите структуру по умолчанию, налагаемую такими структурами, как Maven, Ruby on Rails, ... Для golang вам, вероятно, следует прочитать определенную документацию или blogs , которые могут давать или не давать вам несколько идей.

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

Однако вы должны спроектировать слой данных таким образом, чтобы он хорошо масштабировался. Многие разработчики часто забывают или недооценивают то преимущество, которое они могут получить от кэширования. Ссылки в основном используются в Интернете для ссылки с одного ресурса на другой и дают связи некоторый семантический контекст путем использования четко определенных имен отношений ссылок. Связи ссылок также позволяют серверу контролировать свое собственное пространство имен и при необходимости изменять URI. Но URI - это не только указатели на ресурсы, которые клиент может вызывать, но и ключи для кеша. Кэширование может происходить в нескольких местах. На стороне сервера, чтобы избежать дорогостоящих вычислений или поиска на стороне клиента, чтобы избежать отправки запросов вообще или промежуточных переходов, которые позволяют снять нагрузку с сильно запрашиваемых серверов. Филдинг сделал кэширующим даже ограничение , которое необходимо соблюдать.

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

Если вы реализуете что-то вроде группировки для, например, некоторых футболистов и определенных категорий, к которым они относятся, например, их команд и игроков, которые атакуют или защищаются, у вас может быть ресурс Team A, который включает все плееры как встроенные данные. Внутри БД у вас может быть либо собственная таблица для команд и ссылки на соответствующего игрока, либо команда может быть просто столбцом в таблице игроков. Мы не знаем, и клиент обычно тоже не беспокоится. Однако с точки зрения дизайна вы должны знать о преимуществах и последствиях одновременного включения всех игроков в отношении предоставления ссылок соответствующему игроку или использования смешанного подхода для представления некоторых базовых данных и ссылки для получения дополнительной информации.

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

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

Вопрос о том, должны ли контроллеры содержать бизнес-логику или нет, - это, прежде всего, сомнительный вопрос. Как правильно сказал Джим Уэббер , HTTP, который является де-факто транспортным уровнем REST, является

протокол приложения, доменом приложения которого является передача документов по сети. Это то, что делает HTTP. Он перемещает документы вокруг. ... HTTP - это протокол приложения, но это НЕ ВАШ протокол приложения.

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

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

...