awesome-everything EN
↑ Обратно к восхождению

API

OpenAPI: чтение spec и diff

Суть Читай реальные фрагменты OpenAPI YAML, вердикт oasdiff и сгенерированный клиент, затем выбирай фикс с наибольшим рычагом, чтобы держать contract честным.
Высота — путь к senior
НольJuniorMiddleSenior
Ты на senior-высоте — в орбите
◷ 14 min

Проблемы контракта ловятся в файле spec, в выводе diff и в сгенерированном клиенте. Читай каждый фрагмент, предсказывай влияние на потребителей и выбирай фикс, который senior-инженер делает первым.

Цель

Отработай цикл, через который проходит каждое изменение API: читай схему, предсказывай последствия для breaking changes и codegen и тянись к фиксу, который держит spec несущим.

Фрагмент 1 — слабая схема

components:
  schemas:
    Order:
      type: object
      properties:
        id: { type: string }
        items:
          type: object          # нетипизированный блоб
        total: {}               # вообще без типа
      additionalProperties: true # любые другие ключи разрешены
      # нет массива `required:`
Викторина

Генератор превращает эту схему Order в клиент. Как будет выглядеть сгенерированный тип и каков фикс?

Фрагмент 2 — вердикт oasdiff

$ oasdiff breaking main.yaml pr.yaml
1 breaking changes: 1 error, 0 warning
error  api-required-request-property-added
       in API POST /orders
       added the required request property 'tenantId'
Викторина

PR добавляет tenantId как required-поле в POST /orders, и oasdiff сообщает об этом в CI. Что должен сделать пайплайн и какова совместимая альтернатива?

Фрагмент 3 — переписывание nullability с 3.0 на 3.1

# OpenAPI 3.0
status:
  type: string
  nullable: true

# OpenAPI 3.1 (JSON Schema 2020-12)
status:
  type: [string, "null"]
Викторина

Ты мигрируешь spec на 3.1 и переписываешь nullability вот так. За чем надо следить в тулинге и дифах?

Фрагмент 4 — code-first аннотации

class CreateOrder(BaseModel):
    id: str
    items: list[Item]
    coupon: str | None = None   # optional, nullable

# FastAPI генерирует OpenAPI spec из этой модели.
# Позднее правка делает coupon required:
    coupon: str                 # теперь required, без дефолта
Викторина

В code-first-сетапе инженер делает coupon required, убрав его дефолт. Сгенерированный spec обновляется автоматически. В чём риск и что его закрывает?

Итог

Каждое изменение контракта читается в трёх местах: схема (слабые типы и открытый additionalProperties дают клиенты с any — ужесточай явными типами, массивами required и $ref), diff (oasdiff классифицирует добавление required-поля, удаление поля ответа или сужение типа как breaking — роняй PR и мигрируй совместимо) и направление генерации (code-first синхронен с кодом, но не с потребителями, поэтому ему нужен тот же gate, что и spec-first). OpenAPI 3.1 переносит nullability в type-массив и выравнивается с JSON Schema 2020-12 — проверь поддержку инструментов до миграции. Читай артефакт, предсказывай влияние на потребителя, затем чини на уровне контракта.

Продолжить восхождение ↑OpenAPI: сделай контракт несущим
хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources3
expand
  1. 01
  2. 02
  3. 03

Trademarks belong to their respective owners. Editorial reference only.