Фича-флаги и удалённая конфигурация
config хранит флаги и конфиги для каждого окружения проекта. Приложения читают их
ключом доставки окружения и следят за изменениями через Server-Sent Events.
Флаги
Флаг бывает булевым, строкой, числом или JSON. В каждом окружении он:
- включён: правила проверяются по порядку, затем отдаётся значение по умолчанию (fallthrough);
- выключен: все получают его значение «выкл». Это и есть аварийный выключатель.
Правила сравнивают атрибут контекста вычисления: in, not_in, contains, starts_with, ends_with,
lt, gt, version_gte, version_lt. Любое отдаваемое значение может быть процентной выкаткой,
устойчивой по атрибуту (например, по id пользователя).
xvii config flags --project shop
xvii config set new-checkout on --env preview --project shop
xvii config set banner 'Распродажа до понедельника' --env production --project shop
xvii config set new-checkout off --env production # аварийный выключатель
Конфиги
JSON-документы для каждого окружения, с необязательной проверкой по JSON Schema, версиями, диффами и откатом.
Подходят для лимитов, текстов, списков — всего, что меняется чаще кода.
Чтение в приложении
У каждого окружения есть ключ доставки cfg_…: только чтение, можно отдавать в браузер, можно перевыпустить.
Значения держите несекретными; секреты — в env.
c, err := sdk.New(ctx, "https://config.xvii.network", os.Getenv("XVII_CONFIG_KEY"))
if c.Bool("new-checkout", sdk.Context{"id": userID}, false) {
// …
}
SDK (go.xvii.network/config/sdk) вычисляет локально и следит за потоком изменений.
// https://config.xvii.network/sdk/xvii-config.ts, скопированный в проект
import { XviiConfig } from "./xvii-config"
const config = await XviiConfig.connect("https://config.xvii.network", process.env.XVII_CONFIG_KEY!)
if (config.bool("new-checkout", { id: user.id, plan: user.plan }, false)) {
// …
}
Один файл без зависимостей; Node 18+, Bun, Deno и браузеры. Вычисляет локально так же, как сервер, и
следит за изменениями.
curl -H "Authorization: Bearer $XVII_CONFIG_KEY" https://config.xvii.network/v1/flags
curl -H "Authorization: Bearer $XVII_CONFIG_KEY" https://config.xvii.network/v1/configs/limits
curl -N -H "Authorization: Bearer $XVII_CONFIG_KEY" https://config.xvii.network/v1/stream
GET /v1/ruleset (с ETag) отдаёт всё для локального вычисления; GET|POST /v1/flags вычисляет для контекста
на сервере.
Безопасное использование
- Кэшируйте последний удачный набор правил и ставьте короткий таймаут: сбой config не должен замедлять каждый
запрос.
- Оставляйте проверку здоровья доступной во время режима обслуживания, иначе деплой откатится из-за того, что
выключатель отвечает 503.
- Проверяйте разрушительные выключатели сначала в preview и записывайте для каждого флага значение по
умолчанию и поведение при сбое.
- Распределение по корзинам оставьте config; не пишите второй алгоритм в приложении.
Меняют флаги developer команды; защищённые окружения — только admin. Лимиты config.flags, config.configs.