Модуль 7 · Репозиторий API

Справочник «Стандартизация HTTP API» · модуль 7 · Репозиторий API

Глава 7.1

7.1

Шаблон PR
и формы issue

Изменение контракта начинают с обсуждения, а не с кода. Форму этого обсуждения задают заранее: форма issue собирает предложение, шаблон pull request — проверки перед объединением. Оба — обычные текстовые файлы в репозитории.

Категория
Репозиторий
Уровень
Базовый
Связанные главы
6.4 CI · 7.2 Владельцы кода · 5.4 CHANGELOG и ADR
Зачем это знать
Чтобы изменение контракта обсуждалось до реализации, а не после

§1API First: сначала договорились

Подход, при котором контракт обсуждают и описывают до написания кода, называют API First. Смысл в порядке действий: сначала договорились, как будет выглядеть операция, потом её реализовали.

Код первым
  • операция уже написана
  • обсуждение начинается на ревью
  • замечание = переделка
  • проще согласиться, чем спорить
Контракт первым
  • обсуждается предложение
  • замечание = правка в тексте
  • реализуется согласованное
  • ревью проверяет соответствие

Разница — в объёме переделок. Поменять имя поля в обсуждении значит поправить одну строку текста; поменять его же, когда операция написана, покрыта тестами и выгружена в описание, — исправить код, тесты и описание. Поэтому в учебном проекте порядок записан прямо в форме предложения.

§2Форма предложения изменить API

Файл .github/ISSUE_TEMPLATE/api_change.yml описывает форму, которую GitHub показывает вместо пустого поля ввода.

.github/ISSUE_TEMPLATE/api_change.yml · начало
name: Предложение изменить API
description: Новая операция, поле, параметр или изменение поведения существующей операции
title: "[API] "
labels: ["api-change"]
body:
  - type: markdown
    attributes:
      value: |
        Контракт сначала обсуждается, потом реализуется (API First).
        Прочитайте docs/API_STYLE_GUIDE.md и docs/VERSIONING.md перед заполнением.
titleЗаголовок начинается с [API] — предложения об изменении контракта видно в списке с первого взгляда.узнаваемость
labelsМетка ставится сама. По ней собирается список всего, что предлагают изменить в контракте.отбор
markdownТекст-напоминание. Показан заполняющему, но в готовый issue не попадает.подсказка
поля формы
  - type: dropdown          # что предлагается: операция / поле / поведение / удаление
  - type: input             # операция: метод и путь
  - type: textarea          # какую задачу клиента это решает
  - type: textarea          # предлагаемый контракт
  - type: checkboxes        # совместимость проверена по docs/VERSIONING.md

Обратите внимание на подпись к третьему полю: «Опишите ситуацию, а не решение». Эта подпись переводит разговор с предложенного решения на задачу: вместо «добавьте поле priority» автор пишет «нам нужно показывать срочные обращения сверху». У такой формулировки может найтись другое, более удачное решение.

§3Почему форма, а не пустое поле

Свободный текст в issue гибче, но недостающие сведения приходится выяснять в переписке, по одному вопросу за раз.

Без формыС формой
«Не работает создание тикета»Операция, шаги, ожидаемое и фактическое, X-Request-Id
Три уточняющих вопроса и два дняВсё нужное в первом сообщении
Автор не знает, что важноФорма сама подсказывает, что важно
Метки расставляются рукамиМетка и заголовок ставятся сами

В проекте три формы: предложение изменить API, сообщение об ошибке и проблема с документацией. Плюс файл config.yml, который убирает возможность создать issue без формы и добавляет ссылку на приватное сообщение об уязвимости — об этом в главе 7.2.

§4Шаблон pull request

Файл .github/PULL_REQUEST_TEMPLATE.md подставляется в описание каждого нового изменения. Первый вопрос в нём — о совместимости.

.github/PULL_REQUEST_TEMPLATE.md · тип изменения
## Тип изменения

- [ ] совместимое изменение контракта (MINOR): новая операция, необязательный параметр,
      новое поле ответа
- [ ] исправление без изменения контракта (PATCH)
- [ ] **breaking change** (MAJOR): удаление, переименование, смена типа,
      новое обязательное поле
- [ ] только документация

Автор обязан выбрать один пункт, и это заставляет его сделать вывод о совместимости до того, как о ней скажет oasdiff. Если отметка автора расходится с выводом сборки, это означает одно из двух: автор неверно оценил своё изменение или политика совместимости описана неточно.

таблица изменений контракта
## Изменения контракта

| Операция или схема | Что изменилось |
|---|---|
| PATCH /api/v1/tickets/{ticket_id} | добавлен приём If-Match, ответ 412 |

Таблица нужна ревьюеру: список изменённых файлов показывает, где правки, но не что они означают для клиента. Одной строки на операцию достаточно, чтобы понять смысл изменения до чтения кода.

§5Чек-лист проверок

.github/PULL_REQUEST_TEMPLATE.md · проверки
## Проверки

- [ ] контракт выгружен: `python scripts/export_openapi.py`
- [ ] тесты проходят: `pytest`
- [ ] Spectral без замечаний
- [ ] изменение записано в `CHANGELOG.md`, раздел `[Unreleased]`
- [ ] у новых ответов с ошибкой есть страница вида проблемы в `scripts/build_docs.py`
- [ ] устаревающие элементы помечены `deprecated: true`, указаны замена и дата отключения
- [ ] для архитектурного решения добавлен ADR в `docs/adr/`

Каждый из семи пунктов — правило из предыдущих модулей. Первые три дублируют сборку намеренно: автор выполняет их у себя и не отправляет заведомо непроходящее изменение.

Четыре последних пункта сборка проверить не может:

Запись в CHANGELOGМашина не знает, заметно ли изменение снаружи. Решает человек — и отмечает галочкой.глава 5.4
Страница вида проблемыПоявился новый код ошибки — должна появиться страница, на которую ведёт поле type.глава 4.1
Пометка устареванияУбираете операцию — сначала объявите об этом с заменой и датой.глава 5.3
ADR для решенияВыбор, который затем придётся объяснять другим участникам, записывается отдельным документом.глава 5.4

§6Раздел «Для потребителей API»

последний раздел шаблона
## Для потребителей API

<!-- Что клиентам нужно сделать после выпуска. Если ничего — напишите «ничего». -->

Этот раздел требует от автора оценить изменение со стороны клиента API и сформулировать вывод словами.

Ответ «ничего» здесь допустим и встречается чаще всего; важно, что он написан, — значит, вопрос задавали. Если же ответ не «ничего», его текст переносят в CHANGELOG.md: там нужна такая же формулировка.

§7Как это выглядит вживую

Созданный по форме issue в учебном репозитории: заголовок с префиксом API, метка api-change, заполненные поля
Issue, созданный по форме. Заголовок начинается с [API], метка api-change проставлена автоматически, поля разложены по разделам. Ничего из этого автору вручную делать не пришлось.
Pull request в учебном репозитории с заполненным шаблоном: тип изменения, таблица изменений контракта, чек-лист
Pull request по шаблону. Сверху — что меняется и какого типа изменение, ниже — таблица и чек-лист. Ревьюер получает ответы до того, как откроет вкладку с правками.

Это изменение — демонстрационное: в нём поле updated_at переименовано в modified_at. В шаблоне автор честно отметил тип «breaking change» и в разделе «Для потребителей API» написал, что клиенты, читающие updated_at, перестанут получать значение. Изменение оставлено незакрытым: по нему видно и заполненный шаблон, и красную задачу breaking-changes рядом.

§8Как делают другие

ПроектЧто в шаблонеЧему стоит поучиться
KubernetesТип изменения, заметка для примечаний к выпуску, ссылки на документациюОтдельное поле для текста, который попадёт в примечания к выпуску
OpenAPI InitiativeСсылка на обсуждение, тип правки спецификацииИзменение стандарта требует ссылки на состоявшийся разговор
AzureПодробный чек-лист требований к описанию APIЧек-лист прямо повторяет пункты их свода правил
Шаблон pull request в репозитории Kubernetes
Kubernetes. Обратите внимание на блок примечаний к выпуску: автор пишет текст для пользователей прямо в pull request. Тот же приём, что и раздел «Для потребителей API» из §6, только в большем масштабе.
Формы issue в репозитории Kubernetes: выбор вида обращения
Выбор формы. У крупного проекта форм несколько, и первым шагом автор выбирает вид обращения. В учебном репозитории форм три — по тому же принципу.

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

Шаблон длиннее самого измененияЕго перестают заполнять и стирают целиком. Семь пунктов проверок — верхняя граница.
Пункты, которые уже проверяет сборкаДублировать стоит только то, что автор запускает у себя; остальное — лишний шум.
Нет пункта о совместимостиГлавный вопрос изменения контракта не должен решаться по умолчанию.
Форма без поля «какую задачу это решает»Обсуждается предложенное решение, а не настоящая потребность.
Галочки ставятся не глядяПризнак того, что пунктов слишком много или они бессмысленны. Уберите лишние.

§10Проверьте себя

  1. Что такое API First и почему при таком порядке замечание приводит к меньшему объёму переделок?
  2. Зачем в форме предложения просят описать ситуацию, а не решение?
  3. Что даёт автоматическая метка и префикс в заголовке issue?
  4. Почему первый вопрос шаблона pull request — о типе изменения?
  5. Назовите четыре пункта чек-листа, которые сборка проверить не может, и объясните почему.
  6. Какую работу делает раздел «Для потребителей API», если ответ в нём — «ничего»?
Формы issueapi_change.ymlbug_report.ymldocs_problem.ymlconfig.yml
Шаблон PRчто меняетсятип изменениятаблица контрактапроверкидля потребителей
Принципсначала договорпотом реализация
Мерашаблон короче изменения

Справочник «Стандартизация HTTP API» · модуль 7 · глава 7.1Макаров Максим Николаевич

Кадр