станете ли вы убирать взаимодейтсвия с бд в отдельное приложение? Читал тут вот эту статью: https://medium.com/@cedric_paumard/how-to-build-multiple-web-apps-with-elixir-thanks-to-umbrella-part-2-set-up-the-project-800d6d731dbd - человек предлагает так и сделать. И я подумал: как тогда тесты писать? Так или иначе бизнес-сайд приложения будет тесно связан с базой, не мокать же всё.
Это не самый простой путь, да, нужны дополнительные приседания, причём не всегда понятные. Опять же, феникс очень плохо подходит для разделения на куски, и нет аналога common_test, который пишется в корень проекта
Никогда не выбирал бы зонтичные приложения
почему плохо? Всегда выпиливаю ecto в зонтик и роутеры для непересекающихся подприложений отдельно, в phoenix части часто оставляю только endpoint, аналог ct общий как таковой и не нужен, его всегда можно собрать.
Мокать все.
> Всегда выпиливаю ecto Глупый вопрос, но насколько это этично?
И работу с сетью вынести в отдельное приложение, да? И работу с файлами тоже? И с stdin/stdout?
Ну нет. Просто вынести общую экто часть в отдельный зонтик кажется логичной идеей.
Общую для чего?
У нас сейчас одна база обслуживает два приложения. Внутреннее и для клиентов. На рельсах. Одно приложение, точнее, просто код храним зонтично, в разных папках. Мы подумываем переписать на эликсире.
Логично отделять - то что может быть реюзнуто в нескольких местах - то, что может инкапсулировать в себе некую часть бизнес- или инфраструктурной логики (S из SOLID) Персистенция же сама по себе не является по умолчанию ни первым, ни вторым.
На более глубоком логическом уровне в ваших приложениях существуют данные. Именно данные, их структура, правила их трансформации (из исходных в производные) и определяют одно у вас приложение или два. Если у вас в этой одной базе данные организованы так, что их логически нельзя разделить на "внутренние" и "для клиентов" - то у вас не два приложения, а одно, просто имеет два разных UI. Например, в интернет-магазине есть личный кабинет клиента и админка менеджера по отправке. UI разные, но они оба делают выборку по заказам клиентов. Как это может выглядеть в зонтичном проекте (по трёхтировой схеме): apps customer_ui admin_ui application persistence application содержит контроль инвариантов согласно бизнес-правилам persistence - низкоуровневый инфраструктурный слой, экто там или что-то ещё customer_ui и admin ходят в application за чтобы сделать write или read, в persistence напрямую не ходят. Вот оно как бы просто в теории, а на практике обнаружится, что админке нужно делать какие-то свои выборки, а лк клиента - свои. И в application/persistence начнут появляться методы для этих выборок. А потом, спустя N месяцев уже непонятно будет, зачем существуют те или иные методы. В репозиториях будет по 10 тысяч строк. И тогда начнёшь думать, что может и лучше чтобы админка и лк клиента сами ходили в персистенцию - так хоть понятно было бы, какой код за какой кусок логики отвечает. Так что ответ зависит от размера приложения. Можно и так и эдак. Первичны всегда данные - если их нельзя логически разделить на две разных базы - у вас одно приложение, а не два.
Оп, благодарю за столь подробный ответ :) Порефлексирую над этим на досуге
Хороший ответ, от себя добавлю что помимо горизонтального разделения архитектуры по слоям, есть ещё и вертикальное по контекстам/доменам в котором тоже придётся искать место для базы Вариантов-то всего четыре: 1. База и интерфейс к ней у каждого сервиса/контекста/приложения разные 2. База общая, но интерфейсы разные 3. Базы разные, интерфейс один 4. База общая и интерфейс общий Под базой я имею в виду именно инстанс базы, а под интерфейсом имею в виду схемки, миграции и всё такое. Я почти с каждым из этих случаев так или иначе сталкивался на работе и везде есть плюсы и минусы В первом варианте, всё очень безопасно, сервисы/контексты не зависят друг от друга, но будут проблемы с консистентностью для межконтекстных запросов Во втором варианте, проблем с консистентностью для межконтекстных запросов не будет, но будут проблемы с data race-ами на foreign key, миграциями. Душный вариант, я бы такой не рекомендовал В третьем варианте будут жуткие проблемы с миграциями, каждый сервис будет невольно знать о куче ненужных сущностей. Тоже духота В четвертом варианте не будет проблем с консистентносью, миграциями и всем таким, но интерфейс очень быстро разжиреет и на базу будет очень сильная нагрузка Так что в итоге, четвёртый вариант идеален для маленьких проектов и нагрузок, первый вариант хорош для больших проектов с сильной архитектурой, а второй и третий какие-то уж сильно экзотические и тут нужно понимать что они ведут к сильной связности контекстов, что не всегда хочется иметь в своих проектах
Обсуждают сегодня