# Тема 1. API как публичный контракт программы

Дисциплина «Стандартизация, сертификация и техническое документоведение», 4 курс.
122 слайда: 103 по авторскому сценарию и 19 добавленных 16.09.2026 (части 12–13). Тема рассчитана
на несколько пар: границы частей отмечены в шапке каждого слайда.

## Что студент уносит

- различает стандартизацию (набор правил) и проверку соответствия (доказательство);
- проектирует URI, методы и status codes по семантике HTTP;
- читает и дополняет OpenAPI, понимает связь FastAPI → openapi.json → Swagger UI / ReDoc;
- возвращает ошибки в формате Problem Details (RFC 9457);
- ведёт версию контракта по SemVer, отличает breaking change от совместимого;
- записывает правила в API Style Guide и переводит часть из них в Spectral и тесты;
- оформляет репозиторий API: шаблон PR, формы issue, CODEOWNERS, SECURITY.md, CHANGELOG;
- применяет заголовки контракта: Deprecation и Sunset, 429 и Retry-After, ETag и If-Match, Idempotency-Key, X-Request-Id, CORS;
- находит источник правила и отличает стандарт от черновика и от правил отдельной компании.

## Учебный проект

Репозиторий: https://github.com/MaximBytecamp/api-standard-template (шаблон, кнопка Use this template).
Документация: https://maximbytecamp.github.io/api-standard-template/.

В репозитории есть учебные примеры для показа на паре:

- **PR №6** — breaking change `updated_at → modified_at`. Тесты проходят, oasdiff падает.
  Не сливать: он показывает, что CI останавливает то, что пропустит review.
- **Issue №7** — предложение изменить API в формате формы `api_change.yml`.
- **Защита ветки `main`**: слияние только через PR, обязательны проверки `contract` и `breaking-changes`
  и review владельца кода.
- Pull request от Dependabot, открытые сразу после публикации, — живой пример `dependabot.yml`.

Копия проекта в репозитории курса: `../../api-standard-template/`. Всё, что показано на
слайдах 58–60, 63, 74–76, 80–83, 96–98, 101–102, 106–111, 113–114, — настоящие файлы этого проекта.

```bash
cd api-standard-template
pip install -r requirements.txt
uvicorn app.main:app --reload          # /docs, /redoc, /openapi.json
pytest                                 # 31 тест
python scripts/export_openapi.py --check
npx @stoplight/spectral-cli lint openapi/openapi.yaml
```

Проверено 16 сентября 2026 года на версии 1.1.0: 31 тест проходит, контракт совпадает с кодом,
Spectral замечаний не выдаёт. Источник каждого правила с цитатой и переводом — `docs/STANDARDS.md`. Учебные токены: `demo-token` (запись), `viewer-token` (чтение).

## Части темы

| Слайды | Часть | Что происходит на экране |
|---|---|---|
| 1–3 | Что стандартизируем | контракт, стандартизация и проверка, учебный стенд |
| 4–8 | Запрос, ответ, ресурс | **анатомия сообщения**: легенда подсвечивает части запроса и ответа (6, 7) |
| 9–15 | REST | ограничения Филдинга, HTTP API и REST |
| 16–33 | Правила HTTP API | именование, методы, коды; **демонстрация** safe/idempotent на слайде 28 |
| 34–36 | Практика: контракт | таблица операций; **линтер контракта** на слайде 35 |
| 37–53 | OpenAPI | drift, версии OAS, разделы документа; кадры RFC 9110 и OAS |
| 54–60 | FastAPI и документация | запуск проекта, Swagger UI, openapi.json, ReDoc, схемы |
| 61–65 | Ошибки | RFC 9457, свой Problem Details, вызов 404, диагностика |
| 66–75 | Версии и изменения | четыре номера, SemVer, breaking changes, deprecation, CHANGELOG, ADR |
| 76–86 | Стандарт и его проверка | Style Guide, MUST/SHOULD/MAY, Spectral, контрактные тесты, CI, OWASP |
| 87–94 | Стандарты реальных команд | OAI, Zalando, Microsoft, adidas, GitHub, Redocly, DigitalOcean, Box |
| 95–103 | Репозиторий API на GitHub | один файл у разных компаний: шаблон PR, формы issue, CODEOWNERS, SECURITY.md, CHANGELOG; oasdiff; адрес type; STANDARDS.md |
| 104–113 | Заголовки и совместимость | GitHub и Azure о совместимости, места версии, Deprecation/Sunset, 429, ETag/If-Match, Idempotency-Key, X-Request-Id, CORS, OAuth 2.0 |
| 114–120 | Практическая работа | структура эталона, задание, git, диагностика CI, отчёт, вопросы |
| 121–122 | Итог | процесс разработки API, переход к API Governance |

## Связность и анимации

На первом слайде каждой из 15 частей — **карта частей** (пройденные, текущая) и одна фраза,
которая связывает часть с предыдущей: «Успешные ответы описаны схемами. Ошибкам нужен
такой же единый формат». Проговаривайте её перед заголовком: так видно, почему тема
перешла от одного вопроса к другому.

Анимации служат порядку чтения, а не украшению:

- блоки слайда появляются по очереди — сначала вопрос, затем пример, затем вывод;
- на схемах движения запроса (слайды 5, 13, 36, 86, 121) шаги подсвечиваются по порядку,
  как проходит запрос; на слайде 121 правая колонка начинает подсветку после левой;
- лента жизненного цикла на слайде 73 заполняется слева направо.

При настройке системы «уменьшить движение» и при печати анимации отключены.

## Как вести интерактивные экраны

**Слайды 6–7, анатомия.** Нажимайте части легенды по порядку. Кнопка QUERY PARAMETERS
на слайде 6 намеренно ничего не подсвечивает: в этом запросе параметров нет — это повод
показать пример `?status=open` со слайда 22.

**Слайд 28, повтор запросов.** Нажмите POST три раза — появятся три новых обращения.
Затем PUT дважды — состояние после второго такое же, как после первого. DELETE дважды —
второй ответ `404`, но состояние то же. Вывод: идемпотентность говорит о состоянии
сервера, а не о коде ответа.

**Слайд 35, линтер.** Сначала группа находит нарушения сама, только потом нажимается
«Проверить правилами». Правила названы как в `.spectral.yaml` (`paths-no-verbs`) и
дополнены учебными (`id-in-path`, `collection-plural`, `method-matches-intent`), которых
в проекте нет: они показывают, что правило формулирует команда. Настоящий вывод
Spectral на плохом контракте приведён на слайде 80.

**Слайд 116.** Тот же линтер: студенты вписывают первые endpoints своей области.
После первой проверки результат обновляется при каждом изменении текста.

## Как вести части 12–13

У каждого правила на слайде — **цитата в оригинале, перевод и ссылка**. Статус источника
называйте вслед за цитатой: RFC 9745 — стандарт, RFC 8594 — Informational, черновик про
Idempotency-Key истёк, правила Zalando обязательны только в Zalando.

Второе доказательство на плотных слайдах спрятано в блок «Доказательство» — раскрывайте его,
если группа спрашивает, откуда утверждение.

Все ответы сервера на слайдах 106–111 — настоящие: сняты тестовым клиентом с учебного API 1.1.0.
Воспроизвести можно тестами `tests/test_http_features.py`.

## Места, где сценарий уточнён

- Слайд 39: на 15.09.2026 последняя редакция OAS — **3.2.1** (10.09.2026); 3.2.0 вышла 19.09.2025.
- Слайд 57: FastAPI 0.115 ссылается на `redoc@next`, CDN по нему отвечает 404 — в проекте закреплён `redoc@2.5.4`.
- Слайд 91: README github/rest-api-description говорит о проверке запросов и контрактных
  тестах; утверждение о генерации SDK из сценария убрано, потому что в репозитории оно не подтверждается.
- Слайд 94: в `box/box-openapi/openapi` лежат `openapi-v2025.0.json` и `openapi-v2026.0.json`.
- Слайд 71: корневой `Guidelines.md` Microsoft помечен устаревшим; версию в пути использует Microsoft Graph,
  а Azure передаёт её query-параметром `api-version` — это разобрано на слайде 105.

## Два вида одного материала

- **Колода** `index.html` — для показа на паре: один слайд на экран, полноэкранный режим.
- **Лекция** `lekciya/index.html` — тот же текст по частям для чтения и повторения:
  титульная страница с планом, 15 страниц частей, оглавление внутри части.

Кнопка «Читать лекцией» в шапке колоды (или клавиша L) открывает ту же тему текстом
на месте текущего слайда: со слайда 61 — часть 8, раздел 61. Обратно ведёт кнопка
«Открыть слайдами →» в шапке лекции.

Обе версии собираются из одного файла `content.js`. После правки текста:

```bash
node build_lecture.mjs      # пересобрать страницы лекции
```

Интерактивные блоки (анатомия запроса, повтор запросов, линтер, увеличение кадров)
лежат в `interactive.js` и работают одинаково в колоде и в лекции.

## Навигация

← → / пробел — слайды, Home / End — первый и последний, F — полный экран,
M — содержание, S — источники. Ссылка `index.html#64` открывает слайд напрямую.
Клик по кадру открывает его крупно. «Источники → Печать» выводит все слайды в PDF.
Открывать через HTTP-сервер из корня репозитория: `python3 -m http.server`.
