На выходных провел несколько часов погрузившись в Rust.
В свободное время стараюсь изучать чужие open-source проекты, в этот раз я изучал
lemmy — распределенный аналог Reddit.
Открыл для себя не самую хорошую архитектуру, но при этом нашел несколько интересных крейтов. Самым полезным для меня оказался
config — парсер сложных иерархичных конфигов в структуры Rust.
Задача: у меня есть несколько больших сервисов в виде апишек разного уровня: public, internal, private, admin, у них у всех равный доступ к БД, но некоторые находятся в разных подсетях и хост базы отличается, а также сервисы имеют разные настройки http-сервера, плюс к этому, нужно легко настраивать каждый сервис для локальной разработки.
Раньше: использовался dotenv и длинный список env переменных, при старте приходилось установить весь список переменных, либо вынуждать разработчика клонировать .env.sample и править под себя.
Сейчас: я создаю базовый конфиг в директории config сразу для всех апишек, ещё один базовый конфиг для разных окружений и наконец по ещё одному конфигу для каждой апишки. Могу создать отдельный конфиг для апишки в определенном окружении.
Выглядит так:
config/default.toml
— базовый конфиг для всех
config/default-development.toml
— конфиг для всех апишек во время разработки
config/internal.toml
— конфиг для внутренней апишки
config/public.toml
— для публичной апишки
config/private-production.toml
— для приватной апи в продакшене
Конфиги не перетирают друг друга, а мержатся с учетом структуры(не проверял на массивах). Крейт config поддерживает сразу несколько форматов(toml, hjson, json, ini, yaml), можно писать в удобном формате или даже в разных.
Помимо этого я могу определить локальные конфиги, которые в .gitignore и не попадут в репозиторий. Это удобно, когда нужно запустить сразу все апишки без докера на разных портах, или дать им разные параметры http-сервера, чтобы поймать ошибку. Получается вот такое:
.config.toml
.config-production.toml
.config-internal.toml
.config-internal-production.toml
При этом не обязательно создавать все конфиги из списка, достаточно иметь config/default.toml и любой конфиг из списка по необходимости.
Реализовать такое оказалось делом 10 строк.
Поглядеть можно здесь. Большинство строк файла — определение структур для конфига, в методе Settings::new загружаются конфиги в определенном порядке.
И конечно же, можно любой параметр конфига переопределить через переменные окружения. Например,
server.keep_alive
устанавливается через переменную
ACCESSO_SERVER__KEEP_ALIVE
.
На Youtube
есть канал по Rust, есть видео про Actix, который я использую для бекенда Accesso.