OpenApiConfig: - Добавлена OAuth2 security scheme (authorization_code flow с Keycloak realm `nstart`). Auth/token URLs из ordinis.openapi.oauth.issuer-uri configuration property (default: auth.nstart.space/realms/nstart). - BearerAuth scheme сохранён secondary — для pre-issued tokens из CI/scripts. - Servers list переупорядочен — prod первый, staging второй. - Description обновлён с pointer на /docs/ для full integration guide. application.yml: - springdoc.swagger-ui.oauth: client-id (env override), use-pkce-with- authorization-code-grant=true. Public client `ordinis-swagger` настраивается отдельно в Keycloak — see keycloak-setup-swagger-client.md в ordinis-infra repo. - ORDINIS_OPENAPI_OAUTH_ISSUER_URI env var для override realm на разных окружениях. docs/integration/api/read-endpoints.md: - Swagger UI section обновлён: акцент на Authorize button + Keycloak PKCE login (no client_secret needed), tip про bearerAuth fallback. docs/index.md: - Добавлен tab "Я хочу пощупать API" с link на Swagger UI. После deploy: - https://ordinis.k8s.264.nstart.cloud/swagger-ui.html — Swagger UI - https://ordinis.k8s.264.nstart.cloud/v3/api-docs — OpenAPI spec Authorize → выбрать oauth2 → Keycloak login (PKCE) → Try it out с JWT.
6.0 KiB
Read-side endpoints
Read-API в Ordinis — отдельный deployable (ordinis-read-api, scaled 2× в проде)
работающий на Postgres replica. Запросы из read-api не блокируют writer'а.
Base URL:
| Среда | URL |
|---|---|
| prod | https://ordinis.k8s.264.nstart.cloud/api/v1 |
| staging | https://ordinis.k8s.265.nstart.cloud/api/v1 |
Все endpoints требуют JWT (см. Авторизация).
OpenAPI / Swagger UI
Interactive playground с Keycloak login (PKCE flow, без client_secret):
- Swagger UI:
https://ordinis.k8s.264.nstart.cloud/swagger-ui.html→ нажми Authorize → выбериoauth2→ войдёшь через Keycloak. После login каждый "Try it out" автоматически добавит JWT. - Spec JSON:
https://ordinis.k8s.264.nstart.cloud/v3/api-docs - Spec YAML:
https://ordinis.k8s.264.nstart.cloud/v3/api-docs.yaml
{% note tip %}
Если у тебя уже есть pre-issued service token (например для CI scripts) —
выбери схему bearerAuth в Authorize dialog и paste'ни raw JWT. PKCE flow
тогда не нужен.
{% endnote %}
Из spec'а можно generate'ить клиент:
openapi-generator-cli generate \
-i https://ordinis.k8s.264.nstart.cloud/v3/api-docs \
-g python \
-o ./altum-backend/clients/ordinis
Поддерживаются: Python, TypeScript, Go, Java, Kotlin, Ruby и др.
GET /api/v1/dictionaries
Список доступных справочников (фильтрован по scope JWT'а).
curl -H "Authorization: Bearer $TOKEN" \
https://ordinis.k8s.264.nstart.cloud/api/v1/dictionaries
Response:
[
{
"name": "spacecraft",
"displayName": "Космические аппараты",
"scope": "PUBLIC",
"schemaVersion": "1.0.0",
"recordsCount": 4
},
{
"name": "mission",
"displayName": "Миссии / программы",
"scope": "PUBLIC",
"schemaVersion": "1.0.0",
"recordsCount": 9
}
]
GET /api/v1/{name}/records
{% note warning %}
БЕЗ префикса /dictionaries/! Read-api сидит на /api/v1/{name}/records.
Префикс /api/v1/dictionaries/... — это admin write controller (CRUD), у него
нет bulk-list эндпоинта.
{% endnote %}
Активные записи на момент at (default: сейчас).
Параметры
| Параметр | Тип | Пример | Назначение |
|---|---|---|---|
lang |
string | ru-RU, en-US |
Flatten i18n полей в строку. Короткие ru/en тоже. |
at |
ISO 8601 | 2026-05-04T12:00:00+03:00 |
Bitemporal query — активные на момент. |
as_scope |
string | PUBLIC,INTERNAL |
Legacy для anonymous + allowQueryScope=true. |
Пример
curl -H "Authorization: Bearer $TOKEN" \
"https://ordinis.k8s.264.nstart.cloud/api/v1/spacecraft/records?lang=ru-RU"
Response:
[
{
"businessKey": "RESURS-P-3",
"displayKey": "Ресурс-П № 3",
"scope": "PUBLIC",
"validFrom": "2025-01-01T00:00:00+03:00",
"validTo": "9999-12-31T23:59:59+03:00",
"data": {
"name": "Ресурс-П № 3",
"satelliteTypeCode": "EARTH-OBSERVATION-OPTICAL",
"launchDate": "2024-12-25",
"status": "active"
},
"version": 2
}
]
Без ?lang (raw i18n)
"name": { "ru-RU": "Ресурс-П № 3", "en-US": "Resurs-P No.3" }
С ?lang=ru-RU:
"name": "Ресурс-П № 3"
Если запрошенного языка нет — fallback к default_locale (обычно ru-RU).
GET /api/v1/{name}/records/{businessKey}
Одна запись. Параметры те же что у list.
curl -H "Authorization: Bearer $TOKEN" \
"https://ordinis.k8s.264.nstart.cloud/api/v1/spacecraft/records/RESURS-P-3?lang=ru"
404 Not Found — запись либо не существует, либо закрыта на момент at,
либо вне scope JWT'а (Ordinis скрывает существование).
GET /api/v1/{name}/records/{businessKey}/history
Все версии записи (включая закрытые) для построения истории изменений в UI.
[
{
"version": 1,
"validFrom": "2024-06-01T00:00:00+03:00",
"validTo": "2025-01-01T00:00:00+03:00",
"data": {...},
"txTime": "2024-06-01T10:23:45+03:00",
"changedBy": "admin@nstart.space",
"changeReason": "initial"
},
{
"version": 2,
"validFrom": "2025-01-01T00:00:00+03:00",
"validTo": "9999-12-31T23:59:59+03:00",
"data": {...},
"txTime": "2024-12-30T14:11:22+03:00",
"changedBy": "admin@nstart.space",
"changeReason": "Обновление статуса после успешного запуска"
}
]
Для consumers history endpoint обычно не нужен — это UI-feature.
Spatial filters (geometry)
Если справочник имеет geometry поля (spacecraft.aoi, mission.coverage_area),
поддерживаются bbox + polygon фильтры:
?bbox= (bounding box)
GET /api/v1/spacecraft/records?bbox=37.0,55.0,38.0,56.0
Format: min_lon,min_lat,max_lon,max_lat (WGS84). Возвращает записи где
geometry пересекает bbox через PostGIS ST_Intersects + GiST index.
?polygon= (GeoJSON)
GET /api/v1/spacecraft/records?polygon={"type":"Polygon","coordinates":[[[37,55],[38,55],[38,56],[37,56],[37,55]]]}
Polygon — GeoJSON object (URL-encoded). Сложнее bbox, точнее.
Дальше
- События (Kafka outbox) — push-обновления вместо polling
- Bitemporal — детали
validFrom/validToмодели - Caching — стратегии актуализации