Юрий Белк – Full stack Developer (страница 8)
Контракт как основа: OpenAPI-first
В этой книге мы идём подходом OpenAPI-first: сначала описываем API как контракт, а потом реализуем его на разных языках.
Это дисциплина, которая сначала кажется «лишней бюрократией», но очень быстро окупается:
– фронтенд получает типы и клиент без ручной работы;
– e2e‑тесты знают, что проверять, и могут дополнительно сверять схему;
– разные бэкенды реализуют один и тот же договор, без «творчества»;
– изменения API становятся управляемыми: видно, что сломается.
Наша цель в этой главе простая:
написать openapi.yaml, научиться генерировать из него типы/клиенты и заставить CI проверять, что контракт валиден.
Где живёт OpenAPI в нашем монорепо
Мы договорились: контракт лежит в одном месте.
Структура пакета:
text
/packages/shared-contract
openapi.yaml
/generated
/scripts
– openapi.yaml – главный файл спецификации.
– generated/ – сюда можно складывать сгенерированные артефакты (типы, клиенты).
– scripts/ – скрипты генерации и проверки.
Папки generated и scripts – опциональны, но они помогают держать порядок: «ручной код» отдельно, «генерация» отдельно.
Пишем первый openapi.yaml
Начнём с минимального, но реального API. Нам нужно что-то, что:
1) легко проверить e2e‑тестами;
2) пригодится для health-check;
3) задаст стиль ответов и ошибок.
Сделаем два эндпоинта:
– GET /health – проверка, что сервис жив.
– GET /api/version – показывает версию API (или приложения), чтобы удобно сравнивать окружения.
Создаём файл:
/packages/shared-contract/openapi.yaml
yaml
openapi: 3.0.3
info:
title: Demo API
version: 0.1.0
description: |
Контракт API для учебного проекта.
Все реализации (TS/Python/Java/Go) обязаны ему соответствовать.
servers:
– url: http://localhost:3001
description: Local dev (пример)
tags:
– name: system
description: Системные эндпоинты
paths:
/health:
get:
tags: [system]
summary: Health check
description: Проверяет, что сервис доступен
responses:
"200":
description: OK
content:
application/json:
schema:
$ref: "/components/schemas/HealthResponse"
/api/version:
get:
tags: [system]
summary: API version
description: Возвращает версию приложения/контракта
responses:
"200":