Бизнес-логика в Provisa¶
Проблема¶
У каждой организации есть стандарты для бизнес-логики, и большинство команд им следует. Но с годами, по мере того как системы строятся и заменяются, а команды меняются, логика расползается по ETL-заданиям, дашбордам, API и хранимым процедурам. Каждая часть по отдельности имеет смысл. Часто никто не планировал целое, а ещё чаще никто не планировал целое во времени. Результат знаком: «чистую выручку» считают тремя способами в трёх местах, и никто не может сказать, какой из них верный.
Для отдельных частей этой проблемы у отрасли есть ответы. Слой метрик, который часто продают как семантический слой, определяет «чистую выручку» один раз для всех инструментов. Open Data Product Standard (ODPS) описывает продукты данных, а Open Data Contract Standard (ODCS) описывает контракты данных. Provisa экспортирует оба. Всё это хорошие идеи, и все они набирают популярность, но каждая покрывает лишь одну часть. Главный вопрос в том, как они вписываются в контролируемые, управляемые данные как одна целостная, составная модель. Логике, которая выводит или изменяет данные, нужно то же управление, что и самим данным: кто может её использовать, что она читает и пишет и куда уходят её результаты.
Каналы доставки усугубляют проблему. Логику встраивают в каждый из них: вычисляемое поле в BI-инструменте, правило в обработчике API, фильтр в резолвере приложения. В итоге у каждого канала своя версия истины, и один и тот же вопрос, заданный через два из них, редко получает одинаковый ответ. В конце концов люди сдаются: они начинают принимать этот беспорядок как цену специализации и обслуживания множества разных заинтересованных сторон.
Что такое бизнес-логика¶
Бизнес-логика — это правила, которые создают, изменяют, удаляют или преобразуют данные.
Бизнес-терминология — отдельная вещь. Имена и описания доменов, таблиц и столбцов, а также термины онтологии говорят, что означают данные. Бизнес-логика говорит, что с ними делают.
Три роли¶
Каждое правило играет одну из трёх ролей, и каждую роль можно написать тремя способами:
| Роль | SQL | Внешний вызов | Код |
|---|---|---|---|
| Набор данных | представление, команда-инструкция | API или процедура, возвращающая строки | резолвер кода @table, @stream; команда python или script |
| Значение | выражение представления, метрика | — | команда python или script |
| Изменение | INSERT, UPDATE, DELETE, команда-инструкция |
запись через API, мутация, процедура | @command; команда python или script |
- Внешний вызов. API GraphQL, REST или gRPC другой системы либо хранимая процедура базы данных, зарегистрированные как команда.
- Таблицы как аргументы. Команда может принимать таблицы как аргументы, поэтому набор данных можно построить из других наборов данных.
- Метрика. Именованный агрегат, определённый один раз, например
net_revenueкакSUM(orders.amount) - SUM(orders.refunds). Каждый запрос разбивает его по нужным ему измерениям, поэтому хранилище, дашборд и API читают одно и то же число.
Скрытые побочные эффекты¶
Скрытый побочный эффект — это эффект, которого не видно из определения правила.
Каждое правило имеет имя и тип, зарегистрировано, проходит аудит и защищено. Команда также может требовать одобрения перед запуском.
| Возможные побочные эффекты | Чем ограничены | |
|---|---|---|
| SQL | Нет | — |
| Внешний вызов | Собственные процессы, уведомления и каскады другой системы | Список разрешённого исходящего трафика (HTTP, gRPC); учётные данные, хранящиеся как секреты (процедуры, операции источника) |
| Резолвер кода | Вызовы внешних сервисов и сетей; изменчивые результаты; стоимость | Закреплённый код, закреплённый отпечаток хоста, песочница, учёт |
| Код на хосте | Читает всё, что может прочитать сервер (память, учётные данные, файлы, сеть); может истощить сервер или обрушить его | commands.allow_host_code, по умолчанию выключено |
Внешний вызов типизирован собственной схемой системы или аргументами и возвращаемыми столбцами, которые вы объявляете при регистрации команды.
Код резолвера кода закреплён версией пакета, коммитом Git или хешем архива, поэтому он продвигается вместе с моделью.
Код на хосте — это команда python или script. Он работает внутри сервера с полным доступом сервера, поэтому вредоносный, ошибочный или жадный код может прочитать всё, что может сервер, истощить его или обрушить. Это удобно и безопасно, когда вы доверяете коду. Модель хранит только ссылку (module:attr или командную строку), поэтому код не переносится при продвижении. Он работает только там, где включено commands.allow_host_code.
Эти ограничения сдерживают побочные эффекты, но не могут их устранить. Что делает внешняя система или ваш собственный код, в конечном счёте зависит от них.
Что даёт модель¶
- Логика живёт в модели, а не в канале. Каждый канал (SQL, GraphQL, REST, Arrow Flight, MCP и остальные) читает одни и те же правила, поэтому один и тот же вопрос везде получает один и тот же ответ.
- Каждое правило зарегистрировано в домене, с правами.
- Каждое правило управляется одинаково, как бы оно ни было написано.
- Каждое правило видно в lineage.