- 13 конвенций по осям arch / lang / stack / common; репозитории берут оттуда копии в свой docs/conventions/ и коммитят их у себя - conv — синхронизация копий: add / status / diff / pull / push, локальные регионы исключены из сравнения, поэтому расхождение не даёт шума
3.0 KiB
3.0 KiB
status, extends
| status | extends |
|---|---|
| рекомендуемая | arch/db-identifiers.md |
Идентификаторы: реализация на Go
Как arch/db-identifiers.md выглядит в Go-приложении, выбравшем ULID.
Единая точка — internal/ident
ident.NewID()— генерация. PK сущности генерируется вCreate-методах слояstore. Прочие идентификаторы (батч, задание, корреляционный ключ) генерируются там, где начинается операция, — но тоже только черезident.ident.NewIDAt(t)— генерация с заданным временем, для бэкфилла в Go-миграциях: сортировка id тогда сохраняет историческую хронологию, а не момент прогона миграции.ident.Parse()— разбор и нормализация; зовётся на входных границах (HTTP-роут, форма, callback бота), до обращения к store.- Других генераторов и парсеров id в коде нет. Это то самое «единая точка» из базовой конвенции; без него нормализация регистра неизбежно где-нибудь пропускается.
Типы
В структурах store и домена id — обычный string. Отдельный тип ID
заводим, только если появится вторая семья идентификаторов, которую можно
перепутать; до этого он даёт конверсии без выгоды. От перепутывания двух id
одной семьи в сигнатуре он всё равно не спасает — там помогают имена
параметров.
Невалидный id на границе
Разбор не удался — дальше зависит от того, откуда id пришёл:
- из пути или query URL — сразу 404, без обращения к store и без фабрикации доменной ошибки: снаружи это неотличимо от несуществующей записи, и хорошо;
- из собственной формы или callback-данных кнопки — 400 либо понятное сообщение («кнопка устарела»): это баг интерфейса или протухший экран, и под «не найдено» его маскировать нельзя.
Транспорт не создаёт доменные sentinel'ы, чтобы тут же их сматчить, — это
инверсия правила «трансляция у источника» из lang/go/errors.md.