d5268b9395
Новая документация-as-code на платформе Diplodoc (Yandex open-source) с YFM (Yandex Flavored Markdown). Build → static HTML, deployable куда угодно. Что добавлено: - package.json + .yfm + toc.yaml — Diplodoc setup, навигация для sidebar - index.md — главная страница с tabs для разных audiences - README.md — инструкция для contributors Раздел integration/api/ — 11 страниц про интеграцию consumers: - index — обзор + глоссарий - auth — Keycloak service accounts, scope mapping - read-endpoints — GET /dictionaries, list/by-key, spatial filters - events — Kafka outbox топики, partition keys, idempotency, DLQ - webhooks — HMAC, SSRF guard, retry policy, test ping endpoint - bitemporal — validFrom/validTo + history, future-dated entries, bulk close/export - x-references — FK syntax, validation errors, scope hiding, orphan scanner, v2 cascade preview - caching — TTL / push / snapshot strategies, hybrid pattern - errors — full error code reference (validation/auth/conflict/server), retry strategy - best-practices — 33 numbered rules для consumers - bundle-cuod — все 40 справочников с FK графом и сценариями Обновлены: - ops/README.md — link на новую integration/api/, убран inline <br> - ops/slo.md — broken cross-repo links заменены на text references Build: cd docs && pnpm install && pnpm build → ./_dist (20 HTML files, 7.1M) pnpm serve # → http://localhost:8088 CI deploy job для GitLab Pages — в roadmap (см. docs/README.md). Существующий tech/api-integration.md оставлен в toc как legacy (содержимое мигрировано + расширено в integration/api/).
157 lines
6.9 KiB
Markdown
157 lines
6.9 KiB
Markdown
# Best practices
|
||
|
||
Чек-лист для consumer'ов Ordinis API.
|
||
|
||
## Идентификация записей
|
||
|
||
1. **Используй `businessKey`, не UUID.** UUID — внутренний идентификатор
|
||
записи и **меняется** при создании новой версии (через update).
|
||
`businessKey` стабилен через всю жизнь записи.
|
||
|
||
2. **Не делай FK на копию справочника.** Если копируешь данные к себе для
|
||
snapshot — храни `business_key VARCHAR` как key, не `id UUID` либо
|
||
`internal_id`. Это устойчиво к updates.
|
||
|
||
## Авторизация
|
||
|
||
3. **Кэшируй access token с TTL = `expires_in - 30s`.** Не делай новый
|
||
token request на каждый API call — Keycloak rate limits + латентность.
|
||
|
||
4. **Refresh JWT перед TTL.** Не дожидайся 401 — большинство Keycloak SDK
|
||
рефрешат автоматически.
|
||
|
||
5. **Не храни `client_secret` в коде / git.** Vault либо secret manager.
|
||
|
||
## Чтение
|
||
|
||
6. **Кэшируй per `(dictionary, lang)`.** Inline в коде — `staleTime` /
|
||
TTL. См. [Caching](caching.md).
|
||
|
||
7. **Используй `?lang=` параметр** для flatten i18n полей если UI на одном
|
||
языке. Без `lang` ответ возвращает `{ru-RU: "...", en-US: "..."}`
|
||
объект — лишний размер payload + проще баг.
|
||
|
||
8. **Не запрашивай history endpoint** на hot path. История нужна только
|
||
admin UI / audit. Список + by-key endpoints достаточны для типичного
|
||
consumer.
|
||
|
||
## Запись (admin only)
|
||
|
||
9. **Не пиши массовых update'ов** через одиночные API calls. Ordinis
|
||
оптимизирован под редкие записи и частые чтения. Для bulk import
|
||
используй `POST /admin/bundle/import` (через bundle Maven module).
|
||
|
||
10. **Bulk close через `_bulk-close`** endpoint, не loop одиночных POST.
|
||
Per-record transactions, classification (skipped vs error vs closed),
|
||
меньше latency.
|
||
|
||
11. **Bulk export CSV** через `_export?format=csv` для extracting filtered
|
||
данные в legacy системы.
|
||
|
||
## Обработка событий
|
||
|
||
12. **Idempotency** — события at-least-once, могут прийти дважды. Используй
|
||
`(dictionary, businessKey, txTime, version)` либо `deliveryId` (для webhooks)
|
||
как dedup key.
|
||
|
||
13. **Async обработка** — отвечай webhook'у `202 Accepted` сразу, обрабатывай
|
||
в background. Жёсткий timeout 10s.
|
||
|
||
14. **HMAC verify первым** — до парсинга JSON. Защита от spoofed events.
|
||
|
||
15. **Stale cache на 5xx / timeout** — отдавай старые данные с warn'ом, не
|
||
падай каскадно.
|
||
|
||
## Производительность
|
||
|
||
16. **Parallel-fetch related dictionaries** при cascading select:
|
||
|
||
```ts
|
||
const [spacecrafts, satTypes, instruments] = await Promise.all([
|
||
fetch('/api/v1/spacecraft/records?lang=ru'),
|
||
fetch('/api/v1/satellite_type/records?lang=ru'),
|
||
fetch('/api/v1/instrument/records?lang=ru'),
|
||
])
|
||
```
|
||
|
||
Не последовательные `await`, не N+1 loops.
|
||
|
||
17. **Cascading filters в memory** — после loading dictionaries фильтруй
|
||
клиент-side вместо новых API calls:
|
||
|
||
```ts
|
||
const allowedFormats = formats.filter(f =>
|
||
instrument.data.supportedFormatCodes.includes(f.businessKey))
|
||
```
|
||
|
||
18. **Не делай polling в tight loop** — используй webhooks либо Kafka events
|
||
для realtime invalidation. Polling каждые 5 мин — OK, каждые 10 сек — нет.
|
||
|
||
## Error handling
|
||
|
||
19. **Don't retry 4xx (кроме 401 и 429).** Permanent errors требуют code
|
||
fix, не retry.
|
||
|
||
20. **Exponential backoff на 5xx / timeout.** Base 0.5s, multiplier 2,
|
||
jitter 0-0.5s, max 5 attempts. См. [Errors](errors.md).
|
||
|
||
21. **Сохраняй `traceId`** при эскалации в Ordinis team. Без traceId
|
||
investigation в Tempo занимает в 10x дольше.
|
||
|
||
## Bundle versioning
|
||
|
||
22. **Forward compatibility** — допускай новые поля в API responses которые
|
||
ты не знаешь. Не fail on unknown fields. Schema validation у consumer'а
|
||
должна быть `additionalProperties: true` (либо аналог).
|
||
|
||
23. **Подписывайся на `nsi.dictionary.changed` events** для новых
|
||
справочников — они появляются с минор-bump bundle.
|
||
|
||
24. **Monitor schema versions** в `GET /dictionaries` response — если
|
||
`schemaVersion` поменялся, проверь твой mapping не сломался.
|
||
|
||
## Безопасность
|
||
|
||
25. **HTTPS обязателен** — webhook URLs тоже только https. SSRF guard
|
||
блокирует http:// и private CIDR.
|
||
|
||
26. **Не log access tokens** в plaintext. Большинство logging frameworks
|
||
имеют redaction patterns для `Authorization` header.
|
||
|
||
27. **Rotate `client_secret`** регулярно. Раз в квартал — minimum, раз
|
||
в месяц — recommended для production. Coordinate с Ordinis team
|
||
при rotation.
|
||
|
||
## Коммуникация с командой
|
||
|
||
28. **Прежде чем bulk import** > 1000 records — talk to Ordinis team. У
|
||
нас есть staging environment + bulk-import endpoint без rate limits.
|
||
|
||
29. **Запрашивай новый scope / role** через `zimin.an@nstart.space`
|
||
либо issue с label `keycloak-role-request`.
|
||
|
||
30. **При проблеме**: воспроизведи на staging, скопируй traceId, открой
|
||
issue. Скриншоты UI ошибок помогают.
|
||
|
||
## Тестирование
|
||
|
||
31. **Mock Ordinis в unit tests** — не завись от availability staging
|
||
cluster. Нашa OpenAPI spec accurate, генерируй mock client.
|
||
|
||
32. **Integration tests против staging** — не prod. Staging данные — тестовые,
|
||
можно create/close без последствий.
|
||
|
||
33. **Load tests на staging** в low-traffic окно. Координируй с Ordinis
|
||
team — мы можем включить дополнительные replicas для вашего теста.
|
||
|
||
## Reference: bundle cuod
|
||
|
||
См. [Bundle cuod](bundle-cuod.md) — список 40 справочников, их связи,
|
||
типичные operations.
|
||
|
||
## Дальше
|
||
|
||
- [События](events.md) — push-обновления
|
||
- [Caching](caching.md) — стратегии кэша
|
||
- [Errors](errors.md) — обработка ошибок
|