Перейти к основному содержимому

Предложение (proposal) — OpenAPI-first подход для polyglot кодогенерации (Go + Rust + SDK languages)

Версия: 1.0 Дата: 27.04.2026 Статус: Открытый вопрос (на обсуждение, не утверждённое решение)

Назначение документа

Этот документ — proposal (предложение, не утверждённое решение) о подходе к кодогенерации в polyglot-проекте платформы Vitiana. Документ фиксирует обсуждаемую развилку, варианты, trade-off и рекомендацию для дальнейшего рассмотрения.

Документ не утверждает архитектурное решение. Решение принимается на стадии 1 implementation baseline с участием главного архитектора, future Tech Lead и (опционально) external consultants.

Документ ссылается на текущие зафиксированные принципы платформы и явно не нарушает их — это расширение, не пересмотр.

Контекст развилки

Что уже зафиксировано в платформе

В существующих документах:

Что НЕ зафиксировано (тема этого proposal)

  • Code generation toolchain — конкретные tools (oapi-codegen, OpenAPI Generator, utoipa);
  • OpenAPI-first vs code-first — explicit принцип для polyglot environment;
  • Polyglot generation pipeline — единая openapi.yaml → multiple language outputs;
  • Repository layout для contract specifications;
  • /docs endpoint — конкретная реализация (Swagger UI vs Redoc) для partner experience;
  • Альтернативный backend baseline — Go + Rust вместо TypeScript + Go.

Тезисное обоснование

Тезис 1. OpenAPI-first для polyglot — единственный масштабируемый подход.

Альтернативы:

  • (а) Code-first per language — каждый сервис генерирует свою OpenAPI из аннотаций;
  • (б) Manual sync — OpenAPI поддерживается параллельно с кодом, без генерации;
  • (в) OpenAPI-first — единый openapi.yaml source of truth, генерация типов / клиентов / серверных stubs для всех языков.

Trade-off: вариант (а) приводит к расхождениям между Go-генерируемой OpenAPI и Rust-генерируемой (разные генераторы, разные интерпретации, разные конвенции naming); вариант (б) — manual sync неминуемо устаревает; вариант (в) — single source of truth, генерация всех остальных артефактов автоматически. Это масштабируется на любое количество языков и команд.

Согласовано с принципом «развитие без деградации» — code-first per language создаёт technical debt с момента появления второго языка.

Тезис 2. Repository layout с central openapi.yaml.

Альтернативы:

  • (а) openapi.yaml живёт в каждом сервисе отдельно;
  • (б) Single monorepo с central /api/openapi.yaml;
  • (в) Separate contracts repo (vitiana-contracts) с versioning.

Trade-off: вариант (а) — фрагментация; вариант (б) — все сервисы в одном repo (если monorepo); вариант (в) — контракт как product с явным versioning, может потребляться от любого репозитория.

Recommendation: вариант (в) на стадии 2+ при росте команды; вариант (б) на стадиях 0–1 для simplicity.

Тезис 3. Code generation tools per language.

Каноничный набор:

  • Go: oapi-codegen — direct OpenAPI → Go (server interfaces, models, clients);
  • Rust: OpenAPI Generator — для clients/types из Go API; либо utoipa если Rust сервис sources own OpenAPI (но согласно тезису 1 — Rust как реализация контракта, не источник);
  • TypeScript: openapi-typescript для типов + openapi-fetch для клиента; альтернативно OpenAPI Generator typescript-axios template;
  • Python (для ML services / scripts): openapi-python-client или OpenAPI Generator python template;
  • Documentation UI: Redoc для public partner docs (polished, SEO-friendly), Swagger UI для interactive testing (internal/sandbox).

Тезис 4. Backend baseline — открытая развилка между TypeScript + Go и Go + Rust.

Альтернативы:

  • (а) TypeScript + Go (текущая рекомендация в implementation-technology-baseline.md):
    • максимизация talent pool (TS — широчайший в Восточной Европе);
    • same language frontend ↔ BFF;
    • Go для performance-critical (search, ingestion, payment);
    • быстрое onboarding.
  • (б) Go + Rust (radical performance-first):
    • Go для основной массы services;
    • Rust для security-critical (payment) и ultra-performance (search, real-time pricing);
    • Python только для small utilities/scripts;
    • меньше talent pool в EU/CIS, особенно для Rust;
    • longer learning curve, lower velocity первые 6–12 месяцев.

Trade-off: вариант (а) faster time-to-market, broader hiring; вариант (б) higher performance ceiling, stronger memory safety guarantees, но slower team scaling.

Эта развилка не решается этим документом — это решение стадии 1 совместно с future Tech Lead на основе:

  • talent pipeline analysis (доступные senior Rust engineers в EU/CIS);
  • performance requirements первого production-capable contour;
  • security-critical paths analysis (payment domain — Rust justified?).

Тезис 5. OpenAPI-first как принцип не зависит от выбора языков.

Это ключевая мысль proposal: OpenAPI-first даёт benefit независимо от того, выбран TypeScript+Go или Go+Rust. Поэтому этот принцип может быть зафиксирован независимо от backend language decision.

Конкретные предложения

Предложение 1. Зафиксировать OpenAPI-first как архитектурный принцип

Добавить в api-contracts.md (или в новую секцию documentation-level) следующий принцип:

Принцип OpenAPI-first. Все synchronous API контракты платформы Vitiana поддерживаются как single source of truth в формате OpenAPI 3.1. Реализация сервисов на всех языках (Go, Rust, TypeScript, Python) использует автоматически сгенерированные типы / interfaces / clients из этого единого контракта. Code-first генерация OpenAPI per language запрещена в production code path.

Аналогичный принцип для async контрактов через AsyncAPI.

Предложение 2. Зафиксировать code generation toolchain

Добавить в implementation-technology-baseline.md новую развилку (Развилка 11):

ЯзыкToolНазначениеPhase
Gooapi-codegenserver stubs + models + clientsфаза 1
RustOpenAPI Generator (rust-server template)clients + typesфаза 2+ (если Rust выбран)
TypeScriptopenapi-typescript + openapi-fetchtypes + клиентфаза 1
Pythonopenapi-python-clientclient для scripts/utilitiesфаза 1
DocumentationRedoc (public) + Swagger UI (sandbox)partner-facing docsфаза 2

Предложение 3. Repository layout

Каноничный layout (фаза 1):

vitiana-platform/
├── api/
│ ├── openapi/
│ │ ├── platform-v1.yaml # main platform API
│ │ ├── partner-v1.yaml # partner-facing API
│ │ └── internal-v1.yaml # internal admin API
│ ├── asyncapi/
│ │ ├── domain-events-v1.yaml
│ │ └── webhooks-v1.yaml
│ └── README.md # contract evolution policy reference
├── services/
│ ├── booking-service/ # Go или Rust
│ │ └── generated/ # auto-generated from openapi
│ ├── payment-service/ # Go или Rust
│ │ └── generated/
│ └── ...
├── sdks/
│ ├── typescript/ # primary SDK
│ ├── python/ # auto-generated
│ ├── php/ # auto-generated
│ └── go/ # auto-generated
└── docs/
├── redoc/ # public partner docs (deployable static site)
└── swagger-ui/ # interactive sandbox (internal/auth-gated)

Фаза 2+ — выделение vitiana-contracts как separate versioned repo.

Предложение 4. /docs endpoint в partner experience

Добавить в api-as-product.md явную реализацию documentation portal:

  • https://docs.api.vitiana.com/ — Redoc-rendered public documentation;
  • https://sandbox.api.vitiana.com/docs/ — Swagger UI с interactive testing (auth-gated, partner sandbox);
  • https://api.vitiana.com/openapi.yaml — raw OpenAPI specification (downloadable);
  • https://api.vitiana.com/asyncapi.yaml — raw AsyncAPI specification.

Предложение 5. Контрольные точки в CI/CD

Каноничные validation gates (для будущих implementation slices):

  1. OpenAPI validation — каждый PR с изменением openapi.yaml проходит schema validation;
  2. Breaking change detection — automated diff против main branch (через oasdiff или equivalent);
  3. Code regeneration check — если openapi.yaml изменён, regenerated code в каждом сервисе должен быть committed (no drift);
  4. Documentation regeneration — Redoc bundle re-generated на каждый release;
  5. Compatibility checklist — согласовано с consumer-compatibility-checklist-by-release-unit.md.

Развилки внутри proposal

Если этот proposal принимается, внутри него остаются под-развилки:

Под-развилка A. Single или multiple OpenAPI files

  • Single platform.yaml со всеми endpoints;
  • Multiple files per surface (platform-v1.yaml, partner-v1.yaml, internal-v1.yaml).

Recommendation: multiple files per surface — лучше separation of concerns, разные access controls, разные lifecycles.

Под-развилка B. OpenAPI 3.0 или 3.1

  • 3.0 — broader tool support;
  • 3.1 — full JSON Schema 2020-12 alignment, webhooks support.

Recommendation: OpenAPI 3.1 — более современный стандарт, JSON Schema alignment важен для consistency с AsyncAPI.

Под-развилка C. Linting и style guide

Tools для consistency:

  • Spectral — lint OpenAPI с custom rules (naming conventions, response shapes, tagging);
  • Custom rule set — для Vitiana-specific conventions (например, обязательные correlation_id headers, error envelope format).

Recommendation: Spectral с custom Vitiana rule set.

Под-развилка D. Versioning strategy в OpenAPI

  • URL-based: /v1/..., /v2/...;
  • Header-based: Accept-Version: 2;
  • Hybrid.

Recommendation: URL-based — explicit, easier для caching, partner-friendly.

Под-развилка E. Code generation в monorepo vs distributed

  • Generated code committed (committable artifacts);
  • Generated code in .gitignore, regenerated on build.

Recommendation: committed для traceability и reproducibility; CI verifies no drift.

Согласование с уже зафиксированными принципами

Этот proposal не нарушает существующие правила:

  • Правило 00000 — OpenAPI как platform-first contract, не supplier-shaped;
  • Современные лучшие практики — Stripe / Twilio / Algolia все используют OpenAPI-first;
  • Развитие без деградации — code-first per language создаёт technical debt с самого начала;
  • Тезисное обоснование — этот документ сам построен по принципу;
  • OpenAPI как производный артефакт (api-contracts.md) — proposal расширяет: «производный от чего» = от каноничной модели в reference/, source of truth для генерации кода.

Что нужно решить для закрытия этой развилки

  1. Принцип OpenAPI-first — утвердить или нет (binary decision);
  2. Code generation toolchain — конкретные tools per language;
  3. Repository layout — monorepo vs separate contracts repo;
  4. OpenAPI 3.0 vs 3.1 — version choice;
  5. Backend language baseline — TypeScript + Go vs Go + Rust (отдельная развилка, не блокирует решение по OpenAPI-first);
  6. Documentation portal stack — Redoc + Swagger UI vs alternative;
  7. CI/CD validation gates — какие automated checks обязательны.

Когда принимать решение

Этот proposal открыт для обсуждения. Каноничные триггеры для принятия решения:

  • Фаза 1 implementation baseline — выбор первого production-capable execution contour требует решения по language baseline и code generation tooling;
  • Hiring tech lead — Tech Lead должен участвовать в этом decision как future implementation owner;
  • Первый partner integration (фаза 3) — public documentation portal должен быть готов, что требует ранее принятого decision по toolchain.

Recommended timing: первая декада стадии 1 implementation baseline, с involvement future Tech Lead.

Каноничный итог

Этот документ — proposal, не утверждённое решение. Он:

  • фиксирует развилку и обсуждаемые альтернативы;
  • предлагает рекомендации (OpenAPI-first, oapi-codegen для Go, OpenAPI Generator для остальных, Redoc + Swagger UI);
  • не утверждает финальное решение по backend language baseline (Go + Rust vs TypeScript + Go — отдельная развилка);
  • ссылается на существующие документы без их правки;
  • открыт для дальнейшего обсуждения с future Tech Lead на стадии 1.

Решение по этому proposal принимается в начале стадии 1 implementation baseline.

Связанная документация

Существующие зафиксированные контракты

Связанные development документы

Связанные технологические документы

Архитектурные правила