Школа
Управление

Почему лучше разделить фронтенд и бэкенд?

Пришёл в один стартап. Увидел, что у них бэк (Python/Flask) и фронт (ReactJS) лежат в одном репозитории. Когда я сказал, что было бы хорошо их разделить, то получил вопрос: «А зачем?». С удивлением сказал, что это правильно. А мне в ответ: «Ты можешь конкретнее объяснить, почему это нужно сделать, ибо правда у всех своя?».

И знаете, я не нашёлся чем ответить. Вот не могу объяснить им, почему лучше разделить.

Хотелось бы, чтобы гуру ответил :‑)

Куаныш Идгеев
16 янв 2020
👁 28695   🗩7
Управление

Почему лучше разделить фронтенд и бэкенд?

Пришёл в один стартап. Увидел, что у них бэк (Python/Flask) и фронт (ReactJS) лежат в одном репозитории. Когда я сказал, что было бы хорошо их разделить, то получил вопрос: «А зачем?». С удивлением сказал, что это правильно. А мне в ответ: «Ты можешь конкретнее объяснить, почему это нужно сделать, ибо правда у всех своя?».

И знаете, я не нашёлся чем ответить. Вот не могу объяснить им, почему лучше разделить.

Хотелось бы, чтобы гуру ответил :‑)

Куаныш Идгеев
16 янв 2020
👁 28695   🗩7
Фёдор Борщёв
Программист, стартапер, ИТ‑консультант
Полезно
 15
15
Непонятно
 1
1
Войдите в Бюросферу, чтобы голосовать

Куаныш!

Большие репозитории создают три проблемы — сильное зацепление, ненужную коммуникацию и сложный деплой.

Сильное зацепление

О зацеплении и связности

Стив Макконнел. Совершенный код. Русская редакция, 2019

Когда фронтенд и бэкенд лежат рядом, есть большой соблазн зацепить их вместе — к примеру, вставить какой‑нибудь CSRF‑токен прямо в HTML, который запускает ваше фронтенд‑приложение.

О зацеплении и связности

Стив Макконнел. Совершенный код. Русская редакция, 2019

Пока проект состоит из одного фронтенда и одного бэкенда — это не очень страшно. Но как только вы решите добавить ещё один фронтенд — скажем, сделать мобильное приложение — вам придётся решать все отложенные проблемы интеграции: придумывать протоколы взаимодействия, учиться проксировать запросы или работать с CORS.

Если бы проекты были разъединены с самого начала, у вас бы сами собой появились удобные для работы соглашения и протоколы — REST или GraphQL, авторизация через JWT. Было бы проще привлекать внешние команды — ведь им не приходилось бы изучать код вашего бэкенда, а вам — его дорабатывать под каждый новый фронтенд.

Ненужная коммуникация

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

Бэкендеры не будут думать об инвалидации кэша CSS‑файлов, а фронтендеры не будут знать ничего о маршрутизации запросов. Если у бэкендеров сломалась публикация, фронтендеры могут не ждать, пока её починят, — у них есть отдельный процесс, который обновляет сервер независимо.

Сложный деплой

Используя большие репозитории, вы лишаете себя целого семейства сервисов, которые облегчают работу по публикации вашего приложения. К примеру, Netlify без единой настройки может опубликовать ваш фронтенд на своих серверах, с CDN, HTTP2 и всеми актуальными технологиями. Проекты вроде Zappa и Claudia делают то же самое с бэкендом на питоне и яваскрипте.

К сожалению, если такой сервис не поймёт, что именно лежит у вас в репозитории, то он не сможет вам помочь. Скажем, Netlify наверняка спасует, если увидит репозиторий с Django, в котором фронтенд запрятан куда‑то глубоко и собирается средствами фреймворка.

P. S. Это был совет об управлении разработкой. Хотите больше знать о планировании спринтов, управлении продуктом или о настройке инфраструктуры? Присылайте вопросы.

Управление проектомВеб‑разработка
Полезно
 15
15
Непонятно
 1
1
Войдите в Бюросферу, чтобы голосовать
Отправить
Поделиться
Поделиться
Запинить
Твитнуть

Комментарии

Такой подход оправдан при работе с большими проектами. Для прототипа или сайта небольшого медиа вполне допустимо делать монолитное приложение. Это позволит быстро развиваться и делать проект силами одного человека.

На самом деле, деление бэкенда и фронта по репозиториям может быть не связано с их монолитностью во время работы приложения. Здесь стоит понять: бэк и фронт разделены физически или нет? Если они не разделены, то мы встречаемся с ситуацией, когда фронт зависит от бэка. Это означает, что фронтенд‑разработчик вынужден поднимать у себя бэкенд, чтобы работать. Это означает, что без бэкендера нельзя закрыть большинство задач по фронту. А это дополнительный расход ресурсов команды. Это означает рост технического долга, когда задача разделения обрастает особенностями архитектуры монолита. Их придётся менять со временем, и это дорого.

Если фронтенд отделён от бэка физически, но не в репозитории, перед командой встают две основные проблемы:

  1. Конфликты. Бэкенд может уйти в разработку по нескольким веткам. Может добавиться новая версия АПИ. Тогда, фронт тоже может разделиться по версиям, но как потом слить ветки — большой вопрос. Единый репозиторий не позволит одновременно переводить фронт, скажем, на новый фрэймворк, а бэк — на новую версию АПИ. Точнее, он позволит, но задача по слиянию и задачи по деплою и тестированию могут занять очень много времени.

  2. CI/CD. Отличное решение для проекта — позволить коду деплоиться автоматически. Если фронт и бэк лежат в одном репозитории, будет трудно разделить сценарии развёртывания. Представим себе процесс: фронт делает новый дизайн. Бэк пилит большую задачу. Проект — в продакшене. Деплой в продакшен — несколько раз в день. Каким булет даунтайм при CI если будет разворачиваться весь проект? Каково будет фронтендщику, если от него потребуют вручную разворачивать фронт? Какие слова вспомнит бэкендщик, если деплоймент ХТМЛ‑файлов уронит бэк?

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

Ещё один плюс разделения — безопасность. Свеженанятый для мелких доработок фронтенд‑фрилансер не должен получать возможность скачать код всей внутренней кухни.

Лучше делить на 4 части:

  1. client‑end(s),

  2. front‑end,

  3. middle‑end (collect/join/hub‑end),

  4. back‑end.

Где бэк — микросервисы. А точнее даже — наносервисы. И они уже либо имеют свою встроенную БД, либо коммуницируют с БД, либо она им не нужна.

При этом важно не смешивать внешние API с внутренними (qq) в рамках микросервиса. Внешние API бэка полностью переходят в middle‑end. Это набор сервисов, которые используют один или несколько бэк‑энд сервисов. Фронт общается с мидлом. Клиент с фронтом — как обычно. Типа:
(B1, B2) → M1 → (F1) → C.
При этом фронтов тоже может быть два или несколько, если клиенты сильно отличаются.

В итоге — оптимальное дробление, простор для горизонтального масштабирования. И... коммуникационные задержки. Но зато код легко поддерживать. Любую его часть, даже не являясь опытным. Хотя т. н. опытность в данном случае только навредит. Умелый программист уместит всё это в одном приложении, но через пару лет он и сам в нём не сможет разобраться.

У ребят с развитым API та часть клиента, которая общается с бэком, вручную не пишется, а генерируется из метаданных эндпоинтов бэкэнда (см. OpenAPI, ранее известный как Swagger). Обычно — сразу для нескольких языков. Например, Java‑клиент, С#‑клиент, JS‑клиенты под браузеры и Ноду и так далее. Официальный клиент использует один из них, остальные отдаются для сторонних интеграций.

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

Что касается «сложного деплоя», то мне, как специалисту по сборке и развёртыванию, удобнее, когда внешних сущностей в окружении сборки минимум. Билды в таком случае сложнее сломать.

Но если хочется всё поделить, то ничего не мешает использовать git submodules, которые позволяют подключить один репозиторий внутрь другого, сославшись на конкретный коммит.

Монорепозитории — репозитории, в которых лежат сразу несколько проектов, — часто используют в больших компаниях: Гугле, Фейсбуке, Твитере и прочих. Для них преимущества монорепозиториев — централизация, видимость, полнота, синхронизация и стандартизация — перевешивают все их недостатки.

Вот хорошая подборка статей и обсуждений по преимуществам монорепозиториев:
https://github.com/…/awesome‑monorepo#good‑reads

Здесь не упомянули важное соображение: структура кода отражает рабочий процесс команды. Если у вас фронтенд‑ и бекенд‑разработчики сидят по отдельности и в процессе работы не общаются, заводите два репозитория. Если наоборот, у вас тесное взаимодействие в команде — заводите один репозиторий. Разработчики помогут друг другу развернуть бекенд и настроить сборку фронтенда, и уже в ходе разработки будут прокликивать живой интерфейс с настоящим кодом, а не только писать искусственные тесты и использовать заглушки.

Цель рубрики — обсуждение вопросов дизайна, веб-разработки, переговоров, редактуры и управления.
Комментарии модерируются. Мы публикуем комментарии, которые добавляют к уже сказанному новые мысли и хорошие примеры.

Рекомендуем другие советы