x
 
Куаныш Идгеев
16 января 2020
Советы почтой каждую неделю
Пожалуйста, получите наше письмо, чтобы подтвердить свой адрес:
Вы подписаны на «Советы за неделю»:

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

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

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


Куаныш!

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Поделиться
Отправить

Комментарии

Алексей Наумов
16 января 2020

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

Николай Долганов
16 января 2020

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

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

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

Андрей Бобков
16 января 2020

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

Константин Иванов
16 января 2020

Лучше делить на 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.
При этом фронтов тоже может быть два или несколько, если клиенты сильно отличаются.

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

Алексей Евдокимов
17 января 2020

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

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

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

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


17 января 2020

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

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

Роман Парпалак
9 февраля 2020

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


Цель рубрики — обсуждение вопросов дизайна всех видов, текста в дизайне и взаимоотношений дизайнеров с клиентами.

Мы публикуем комментарии, которые добавляют к уже сказанному новые мысли и хорошие примеры. Мы ожидаем, что такие комментарии составят около 20% от общего числа.

Решение о публикации принимается один раз; мы не имеем возможности комментировать или пересматривать свое решение, хотя оно может быть ошибочно. Уже опубликованные комментарии могут быть удалены через некоторое время, если без них обсуждение не становится менее ценным или интересным.

Вот такой веб 2.0.

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




Недавно всплыло

Каким должно быть ресторанное меню на сайте? 1 1 Как улучшить запись автоответчика? 4 Как вы справляетесь с разнобоем? 4