iac/apps/mapper/openapi.yaml

231 lines
9.2 KiB
YAML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

openapi: 3.0.3
info:
title: Mapper Service API
version: "1.0.0"
description: |
REST API сервиса **mapper** (flows mapper) — mini-HTTP-сервис, который
объединяет (мапит) данные нескольких сервисов Sarex: документы дисков из
сервиса документации (`documentations`) обогащаются review-данными из
сервиса процессов (`flows`); заметки из сервиса `notes` обогащаются
связями (target-links) из Django-бэкенда.
Сервис написан на Python (**FastAPI**), приложение создаётся в
`src/app/main.py` (`app = FastAPI()`), маршруты — в `src/app/routers.py`
с префиксом `API_PREFIX` (по умолчанию `/api/v1`).
### Аутентификация
Оба эндпоинта требуют заголовок `Authorization`. Опциональный заголовок
`Identity` включает режим Zitadel. Подпись JWT **не проверяется**
(`verify_signature=False`, `src/app/dependensies.py`) — доверие к токену
обеспечивается сетевым слоем (Istio/ingress). Из токена извлекается
`user_id`, который используется как часть ключа кеша Redis.
### Агрегация и кеш
Каждый запрос обращается к двум внешним сервисам через `ServiceManager`
(`src/app/utils.py`). При `REDIS_USE=True` успешные (200) ответы апстрима
кешируются в Redis (ключ `"{user_id}_{url}"`, TTL `REDIS_EXPIRE_DAYS`
суток), а при ошибке апстрима отдаётся кеш. Если хотя бы один апстрим
вернул ошибку и кеша нет — сервис отвечает `400 Bad Request`.
Схемы ответов заданы как свободные JSON-структуры (`object`/`array`),
так как сервис проксирует и объединяет ответы внешних сервисов без
фиксированной модели.
servers:
- url: https://api.sarex.io/mapper
description: production (Sarex)
- url: https://stage-api.sarex.io/mapper
description: stage (Sarex)
- url: https://cde.brusnika.ru/mapper
description: production (Brusnika)
- url: https://test.sarex.brusnika.tech/mapper
description: stage (Brusnika)
tags:
- name: documents
description: Документы дисков, обогащённые review-данными процессов
- name: notes
description: Заметки, обогащённые связями (target-links)
paths:
/api/v1/disks/{disk}/documents/:
get:
tags:
- documents
summary: Документы диска с review-данными
operationId: get_documents
description: |
Возвращает документы диска из сервиса документации, обогащённые
review-данными из сервиса процессов. Внутри выполняются запросы
`GET {DOCUMENTATION_HOST}/disks/{disk}/documents` и
`GET {FLOW_HOST}/documents/?full=true`, после чего review-данные
добавляются в поле `review_data` соответствующих бандлов документов
(`modify_pdm_data`).
security:
- bearerAuth: []
parameters:
- name: disk
in: path
required: true
description: Идентификатор диска
schema:
type: string
- name: Authorization
in: header
required: true
description: Токен доступа (пробрасывается во внешние сервисы)
schema:
type: string
- name: Identity
in: header
required: false
description: Identity-токен (включает режим Zitadel)
schema:
type: string
responses:
"200":
description: Успешный ответ
content:
application/json:
schema:
$ref: "#/components/schemas/DocumentsResponse"
"400":
description: Один из внешних сервисов недоступен и данных в кеше нет
"401":
description: Отсутствует заголовок Authorization
"422":
$ref: "#/components/responses/ValidationError"
/api/v1/notes/{service}/{entity}/{instance_id}/:
get:
tags:
- notes
summary: Заметки сущности со связями (target-links)
operationId: get_notes
description: |
Возвращает заметки сущности из сервиса `notes`, у которых поле `links`
заменено на объекты связей (target-links) из Django-бэкенда. Внутри
выполняются запросы
`GET {NOTE_HOST}/notes/{service}/{entity}/{instance_id}/?full=true`
(с проброской всех query-параметров запроса) и
`GET {DJANGO_HOST}/core/target-links/`, после чего выполняется
объединение (`modify_notes_data`).
security:
- bearerAuth: []
parameters:
- name: service
in: path
required: true
description: Логическое имя сервиса-владельца сущности
schema:
type: string
- name: entity
in: path
required: true
description: Тип сущности
schema:
type: string
- name: instance_id
in: path
required: true
description: Идентификатор экземпляра сущности
schema:
type: string
- name: Authorization
in: header
required: true
description: Токен доступа (пробрасывается во внешние сервисы)
schema:
type: string
- name: Identity
in: header
required: false
description: Identity-токен (включает режим Zitadel)
schema:
type: string
responses:
"200":
description: |
Успешный ответ — список заметок. Все дополнительные query-параметры
запроса проксируются в сервис заметок.
content:
application/json:
schema:
$ref: "#/components/schemas/NotesResponse"
"400":
description: Один из внешних сервисов недоступен и данных в кеше нет
"401":
description: Отсутствует заголовок Authorization
"422":
$ref: "#/components/responses/ValidationError"
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
description: |
Токен передаётся заголовком `Authorization`. Подпись не проверяется
приложением. Для режима Zitadel дополнительно передаётся заголовок
`Identity`.
responses:
ValidationError:
description: Ошибка валидации параметров запроса
content:
application/json:
schema:
$ref: "#/components/schemas/HTTPValidationError"
schemas:
DocumentsResponse:
type: object
description: |
Ответ агрегатора документов. Структура повторяет ответ сервиса
документации, где в бандлы добавлено поле `review_data` с данными
из сервиса процессов.
properties:
documents:
type: array
items:
type: object
additionalProperties: true
additionalProperties: true
NotesResponse:
type: array
description: |
Список заметок сервиса `notes`, где поле `links` каждой заметки
заменено на объекты связей (target-links).
items:
type: object
additionalProperties: true
ValidationErrorItem:
type: object
properties:
loc:
type: array
items:
anyOf:
- type: string
- type: integer
msg:
type: string
type:
type: string
required:
- loc
- msg
- type
HTTPValidationError:
type: object
properties:
detail:
type: array
items:
$ref: "#/components/schemas/ValidationErrorItem"