Справочник «Стандартизация HTTP API» · модуль 8 · Практика
Глава 8.1
Свой API
по правилам
В предыдущих модулях разбирался готовый контракт. Практическая работа состоит в том, чтобы составить свой: выбрать предметную область, описать операции, реализовать их и настроить проверки, которые не дадут контракту разойтись с кодом. Работа выполняется по шагам, каждый шаг опирается на отдельную главу справочника.
- Категория
- Практика
- Уровень
- Итоговый
- Связанные главы
- весь справочник · 8.2 Отчёт и критерии
- Что получится
- Репозиторий с работающим API, описанием, проверками и документацией
§1Что нужно сделать
Собрать репозиторий со своим HTTP API: не копию учебного, а свой — по своей предметной области, но по тем же правилам.
| Часть работы | Минимум | Где разбиралось |
|---|---|---|
| Ресурс и адреса | Одна коллекция и её элементы | глава 1.3 |
| Операции | Пять: список, создание, чтение, изменение, удаление | главы 2.2, 2.3 |
| Описание OpenAPI | Выгружено в файл, в репозитории | главы 3.1–3.3 |
| Ошибки | Problem Details, не меньше четырёх кодов | глава 4.1 |
| Заголовки | X-Request-Id обязательно, дальше по выбору | глава 4.3 |
| Версия | Путь /api/v1 и info.version по SemVer | глава 5.1 |
| Стандарт | Свой API_STYLE_GUIDE.md с уровнями требований | глава 6.1 |
| Проверки | Тесты и линтер, запускаются в сборке | главы 6.2–6.4 |
| Документы | README, CHANGELOG, один ADR | главы 5.4, 7.1 |
Учебный проект api-standard-template — образец, а не заготовка для копирования. Обращаться к нему при выполнении работы следует, но переносить целиком нельзя: предметная область другая, а вместе с ней другими будут ресурсы, поля и ошибки.
§2Шаг 1. Предметная область
Выберите область, в которой вы можете без дополнительных источников назвать сущность, её состояния и операции над ней.
Заявки на оборудование, бронирование аудиторий, читательские формуляры, заказы в столовой, задачи в личном планировщике, записи в очередь к врачу.
«Соцсеть», «маркетплейс», «CRM» — слишком крупно: за занятие не получится ни описать, ни реализовать, ни проверить.
Проверьте выбор так: опишите, что происходит с одной записью от создания до удаления. Если описание не укладывается в несколько предложений, область слишком велика и её нужно сузить.
Предметная область: бронирование аудиторий. Сущность: бронь аудитории на дату и пару. Состояния: requested → confirmed → cancelled. Кто пользуется: староста (создаёт), диспетчер (подтверждает), все (читают).
§3Шаг 2. Ресурсы и адреса
Из описания области выделите ресурс и назовите адреса по правилам главы 1.3.
- Существительное во множественном числе для коллекции:
/bookings, а не/bookingи не/createBooking. - Идентификатор в пути для элемента:
/bookings/{booking_id}. - Фильтры и пагинация — параметрами запроса:
?status=confirmed&limit=20&offset=0. - Префикс версии впереди:
/api/v1/bookings. - Не глубже двух уровней вложенности. Нужен третий — скорее всего, там прячется отдельный ресурс.
GET /api/v1/bookings список, фильтр по status, пагинация
POST /api/v1/bookings создать бронь
GET /api/v1/bookings/{booking_id} прочитать одну
PATCH /api/v1/bookings/{booking_id} изменить состояние или примечание
DELETE /api/v1/bookings/{booking_id} отменить и удалить запись§4Шаг 3. Операции и коды
Для каждой операции выпишите все исходы — успешные и нет. Удобно делать это таблицей: она потом прямо превращается в раздел responses описания.
| Операция | Успех | Ошибки |
|---|---|---|
GET /bookings | 200 | 422 — неверный limit |
POST /bookings | 201 + Location | 401, 403, 422 |
GET /bookings/{id} | 200 + ETag | 404 |
PATCH /bookings/{id} | 200 | 401, 403, 404, 412, 422 |
DELETE /bookings/{id} | 204 | 401, 403, 404 |
Проверьте себя тремя вопросами из главы 2.3: возвращаете ли вы 201 именно при создании, 204 именно при удалении, и различаете ли 401 и 403. Это три наиболее частых упрощения, и все три проверяются в первую очередь.
§5Шаг 4. Схемы и ошибки
Опишите данные. Схем должно быть не меньше трёх — по главе 3.3:
class BookingCreate(BaseModel): # что присылает клиент class BookingUpdate(BaseModel): # изменение, все поля необязательны class Booking(BaseModel): # что возвращает сервер class BookingPage(BaseModel): # страница списка: items, total, limit, offset
extra="forbid": клиент не присылает поля, которые формирует сервер.строгостьДальше — ошибки. Используйте формат Problem Details из главы 4.1 и не собирайте тело ошибки в каждом обработчике: один модуль, одна функция, три обработчика исключений.
Если поле type ведёт на адрес, по нему должна открываться страница. Публиковать её на GitHub Pages (глава 7.3) — плюс к работе; если публикации не будет, используйте about:blank, а не выдуманный домен.
§6Шаг 5. Реализация
Только теперь пишется код. Порядок такой же, как в учебном проекте.
структура репозитория
main.py, schemas.py, problems.py, storage.py, операции--check для сборкиХранилище можно держать в памяти — база данных в этой работе не проверяется. Требуется другое: поведение должно совпадать с описанием, а состояние — сбрасываться между тестами.
uvicorn app.main:app --reload
# откройте http://127.0.0.1:8000/docs и выполните каждую операцию кнопкой Execute§7Шаг 6. Проверки
operationId, теги, описанные ответы; все пути с префиксом версии; ошибки — application/problem+json.глава 6.3401, 403, 404, 422. Минимум — двенадцать тестов.глава 6.3export_openapi.py --check: выгруженное описание совпадает с кодом.глава 3.1spectral:oas плюс минимум одно своё правило из вашего стандарта.глава 6.2Склонируйте свой репозиторий в пустую папку, установите зависимости и запустите проверки. Если всё зелёное без единой правки «по месту» — работа собрана правильно.
§8Шаг 7. Документы репозитория
| Файл | Что в нём | Глава |
|---|---|---|
README.md | Что за API, как запустить, ссылка на документацию и стандарт | — |
docs/API_STYLE_GUIDE.md | Свои правила с MUST, SHOULD, MAY и способом проверки каждого | 6.1 |
docs/VERSIONING.md | Что считаете несовместимым изменением и почему | 5.2 |
docs/adr/0001-….md | Одно архитектурное решение с вариантами и последствиями | 5.4 |
CHANGELOG.md | Хотя бы одна запись версии по Keep a Changelog | 5.4 |
.github/PULL_REQUEST_TEMPLATE.md | Свой шаблон с типом изменения и чек-листом | 7.1 |
Стандарт пишется под ваш API. Переписывать в него правила про Idempotency-Key, если вы этот заголовок не поддерживаете, не нужно: правило, которого нет в коде, на проверке заметно сразу.
§9Порядок работы с Git
- Отдельная ветка на изменение. Не пишите в
mainнапрямую — иначе не увидите, как работают проверки в pull request. - Небольшие изменения. «Добавил операцию + тесты + запись в CHANGELOG» — хороший размер. «Сделал всё» — плохой.
- Описание изменения по своему шаблону. Заполняйте его честно, включая тип изменения.
- Дождитесь сборки. Красная — читайте вывод, он написан для вас.
- Объединяйте только зелёное. Это и есть привычка, ради которой строилась вся глава 6.4.
Заведите хотя бы один pull request с намеренно несовместимым изменением и покажите, что проверка его поймала, — как это сделано в учебном репозитории. Такое изменение не объединяют — оно остаётся в репозитории как подтверждение того, что проверка работает.
§10Частые ошибки
200Создание — 201, удаление — 204, ненайденное — 404.Справочник «Стандартизация HTTP API» · модуль 8 · глава 8.1Макаров Максим Николаевич