Автодокументация: OpenAPI, Swagger и ReDoc

FastAPI автоматически строит схему OpenAPI из ваших типов, моделей и описаний и отдаёт по ней две интерактивные документации: Swagger UI (/docs) и ReDoc (/redoc).

Документация в FastAPI — не отдельная работа, а побочный продукт типизации. Та же аннотация, что валидирует данные, описывает их и в OpenAPI-схеме — едином машинно-читаемом контракте API.

OpenAPI — это стандарт описания REST-API в формате JSON/YAML: какие есть эндпоинты, какие параметры и тела они принимают, что возвращают, какие коды ошибок. FastAPI генерирует этот документ автоматически, читая ваши маршруты и модели. По нему он рисует два UI: Swagger UI с возможностью отправлять запросы прямо из браузера и ReDoc с аккуратной читаемой структурой. Доступна и сырая схема по /openapi.json — её можно отдать фронтенду для генерации клиента.

Документацию обогащают метаданными: summary и description у эндпоинтов, examples у полей, tags для группировки, responses для описания кодов ошибок:

@app.get(
    "/items/{item_id}",
    summary="Получить товар по id",
    description="Возвращает товар или 404, если он не найден.",
    responses={404: {"description": "Товар не найден"}},
    tags=["items"],
)
async def get_item(item_id: int):
    ...

Как работает под капотом

FastAPI обходит таблицу маршрутов и для каждого собирает описание: путь, метод, параметры (из сигнатуры), схему тела и ответа (из Pydantic-моделей). Получается один большой JSON по стандарту OpenAPI. Смоделируем генерацию мини-схемы на stdlib:

import json

routes = [
    {"method": "GET",  "path": "/items/{item_id}",
     "params": [{"name": "item_id", "in": "path", "type": "integer"}],
     "summary": "Получить товар"},
    {"method": "POST", "path": "/items",
     "body": {"name": "string", "price": "number"},
     "summary": "Создать товар"},
]

def build_openapi(routes):
    paths = {}
    for r in routes:
        entry = {"summary": r.get("summary", "")}
        if "params" in r:
            entry["parameters"] = r["params"]
        if "body" in r:
            entry["requestBody"] = {"schema": r["body"]}
        paths.setdefault(r["path"], {})[r["method"].lower()] = entry
    return {"openapi": "3.1.0", "paths": paths}

schema = build_openapi(routes)
print(json.dumps(schema, ensure_ascii=False, indent=2))

Попробуй сам ▶ Из списка маршрутов получился машинно-читаемый контракт — упрощённый аналог /openapi.json, по которому рисуются Swagger и ReDoc.

Та же схема в формате JSON, который FastAPI отдаёт по /openapi.json:

{
  "openapi": "3.1.0",
  "paths": {
    "/items/{item_id}": {
      "get": { "summary": "Получить товар" }
    }
  }
}

Частые ошибки

Первая — писать документацию руками в отдельном файле, тогда как она генерируется из кода и должна жить в нём (summary, description, модели). Вторая — игнорировать типы и модели, из-за чего схема выходит бедной. Третья — забывать описывать коды ошибок через responses, оставляя контракт неполным. Четвёртая — открывать Swagger UI в продакшене без надобности; иногда его скрывают.

Best practices

  • Обогащайте эндпоинты summary, description, tags и responses.
  • Описывайте модели и примеры — Swagger покажет их во вкладке схем.
  • Используйте /openapi.json для генерации типизированных клиентов фронтенда.
  • В проде при необходимости отключайте/защищайте /docs.

Контракт-первый подход и генерация клиентов

OpenAPI-схема — это не просто документация для людей, а машинно-читаемый контракт, из которого можно автоматически генерировать код. Фронтенд-команда берёт ваш /openapi.json и инструментом-генератором получает типизированный клиент: функции на каждый эндпоинт, типы на каждую модель, без ручного описания запросов. Любое изменение контракта на бэкенде сразу отражается в перегенерированном клиенте, и несовместимости всплывают на этапе сборки, а не в продакшене. Это превращает документацию в живой источник истины, связывающий бэкенд и фронтенд единым контрактом. Поэтому качество вашей типизации имеет двойную отдачу: оно не только делает Swagger красивым, но и напрямую определяет, насколько удобным и безопасным будет автогенерированный клиент. Чем точнее модели и описания, тем меньше ручной и ошибкоопасной работы у потребителей API.

Итог: OpenAPI-схема генерируется из ваших типов и моделей; по ней доступны Swagger UI и ReDoc. Документация — побочный продукт типизации, и её качество прямо зависит от качества аннотаций и метаданных.

Проверьте себя
1. Откуда FastAPI берёт данные для генерации OpenAPI-схемы?
AИз отдельного YAML-файла, который пишут вручную
BИз ваших маршрутов, аннотаций типов и Pydantic-моделей
CИз базы данных
DИз заголовков запросов
2. Чем Swagger UI (/docs) отличается от ReDoc (/redoc)?
AЭто один и тот же интерфейс
BSwagger UI позволяет отправлять запросы прямо из браузера, ReDoc — аккуратная читаемая документация; оба строятся по одной OpenAPI-схеме
CReDoc генерирует код, а Swagger нет
DSwagger работает только с GET