Приложение C. Файл схемы и реестр
oxl.schema.lock фиксирует теги полей, вариантов и rpc, чтобы схема пакета менялась только совместимо (§9.2). Файл создаёт и обновляет компилятор; ручная правка допускается, но проверяется при сборке.
C.1 Формат#
TOML, кодировка UTF-8, ключи отсортированы, чтобы диффы были стабильными.
format = 1
package = "shop"
published = "0.3.0" # последняя опубликованная версия
[types."shop.orders.Order"]
kind = "data"
version = 1 # @v(n)
fields.id = { tag = 1, type = "shop.model.OrderId" }
fields.userId = { tag = 2, type = "shop.model.UserId" }
fields.total = { tag = 4, type = "shop.model.Money", repr = "i64" }
fields.status = { tag = 6, type = "shop.model.Status", since = 1 }
reserved = [3, 5] # удалённые теги, навсегда
renamed = { receipt = "receiptId" }
[types."shop.model.Status"]
kind = "enum"
open = true
variants = { New = 1, Paid = 2, Shipped = 3, Cancelled = 4 }
[services."shop.orders.Orders"]
version = 1
rpcs.recent = { tag = 1, attrs = ["readonly"] }
rpcs.create = { tag = 3, attrs = ["idempotent", "internal"] }
[codecs]
"shop.model.Money" = { schema = "sha256:9f2c…" } # хеш Codec.schema() или Repr- Ключ типа — полное имя
пакет.модуль.Тип. type— полное имя типа поля после раскрытия псевдонимов; у дженериков — с аргументами (List<shop.model.Item>).reserved— теги удалённых полей и вариантов; переиспользовать их нельзя.codecs— хеш схемы пользовательского кодека илиRepr(§9.5), чтобы замечать смену представления.
C.2 Обновление при сборке#
- Компилятор строит схему из исходников и сравнивает её с lock-файлом.
- Новые поля и варианты получают
max(теги, reserved) + 1, новые rpc — следующий номер в сервисе. - Поле, удалённое с
@removed(n), переносится вreserved. Удалённое без@removed— ошибкаschema-break. - Совместимые изменения записываются в файл автоматически; несовместимые (§9.2) — ошибка с указанием поля и правила.
oxl build --locked(для CI) запрещает менять lock-файл: схема должна быть уже закоммичена.
C.3 Сверка с реестром#
Сравнение идёт с последней опубликованной версией, а не только с локальным файлом — иначе удалённый и пересозданный lock обошёл бы проверку.
oxl publishзагружает из реестра lock-файл версииpublished(реестр хранит lock-файл каждой опубликованной версии).- Сравнивает его с текущей схемой по правилам §9.2.
- Определяет минимально допустимый шаг версии:
| Изменение | Минимальная версия |
|---|---|
только внутренний код, схема pub(api) не изменилась | patch |
добавлены поля, варианты @open enum, rpc, типы | minor |
| любое ломающее изменение из §9.2 | major, и затронутые типы и сервисы ДОЛЖНЫ получить @v(n+1) |
- Если версия в
oxl.tomlменьше минимальной — отказ с объяснением. - После публикации реестр сохраняет lock-файл, а
publishedв локальном файле обновляется.
C.4 Проверка между версиями#
oxl check --against <версия|файл>сверяет схему с lock-файлом другой версии, например работающей в проде.- При rolling upgrade узлы сравнивают хеши схем; узел с несовместимой схемой не получает трафик и отмечается в веб-интерфейсе.
Исходник: docs/spec/oxl-standard.md