Перейти к содержанию

HTTP API backend-приложений

Требования применяются к HTTP API backend-приложений. Уровни обязательности определены в корневом README.md.

BE-HTTP-001. Ограничение HTTP-запроса

Уровень: MUST

Применяется к: каждому входящему HTTP-запросу

Сервер должен задавать конечные timeout чтения заголовков и тела, обработки ограниченного запроса и записи ограниченного ответа, а также максимальные размеры заголовков и тела. Превышение лимита должно завершаться стабильным статусом без передачи избыточного тела в прикладной обработчик.

Намеренно долгоживущий поток MAY не иметь общего timeout ответа, но должен иметь конечные timeout установления и отсутствия прогресса, а также ограничения буферов по BE-RES-001 и BE-RSRC-001.

Обоснование

Границы защищают память, соединения и исполнители от медленных и чрезмерных запросов.

Проверка

  • тест медленного и превышающего лимит запроса;
  • проверка конфигурации сервера;
  • нагрузочный тест исчерпания соединений.

Исключения

Конкретные значения определяются контрактом API и конфигурацией поставки.

BE-HTTP-002. Единый контракт ошибок

Уровень: MUST

Применяется к: каждому неуспешному ответу опубликованного HTTP API

API должен возвращать версионируемый структурированный формат ошибки со стабильным машинным кодом и понятным сообщением. Статус HTTP и код ошибки должны различать валидацию, аутентификацию, авторизацию, отсутствие ресурса, конфликт, rate limit по BE-HTTP-011 и технический отказ, если эти исходы применимы.

Ответ не должен раскрывать stack trace, внутреннее исключение, SQL, адрес зависимости или секрет. Отсутствующее поле должно отличаться от пустого, нулевого или фиктивного значения.

Обоснование

Стабильная ошибка позволяет клиенту действовать без разбора текста и не раскрывает реализацию.

Проверка

  • contract-тест каждого класса ошибки;
  • проверка ответа при необработанном исключении;
  • security-тест утечки внутренних данных.

Исключения

Формат определяется опубликованным API-контрактом проекта.

BE-HTTP-003. Идемпотентность изменяющих операций

Уровень: MUST

Применяется к: повторяемому запросу, создающему необратимый эффект

API-контракт должен определить идемпотентность операции. Для операции, которую клиент вправе безопасно повторить после неопределённого результата, сервер должен принимать ключ идемпотентности, атомарно связывать его с запросом и возвращать тот же существенный результат повтору.

Один ключ с отличающимся существенным содержимым должен отклоняться. Срок хранения результата должен быть не меньше документированного окна повторов.

Обоснование

Ключ предотвращает повторный эффект после timeout или потери ответа.

Проверка

  • конкурентный contract-тест одинакового ключа;
  • тест того же ключа с другим содержимым;
  • тест повтора до и после фиксации результата.

Исключения

Операция, контракт которой запрещает автоматический повтор, может не поддерживать ключ идемпотентности.

BE-HTTP-004. Ограниченные коллекции

Уровень: MUST

Применяется к: HTTP endpoint, коллекция которого может превысить установленный максимальный размер одного ответа

Endpoint должен применять pagination с конечным максимальным размером страницы и детерминированным порядком. Cursor или иной маркер продолжения не должен давать доступ к данным вне полномочий вызывающего субъекта. Изменение данных между страницами должно иметь определённую семантику пропусков и повторов.

Обоснование

Неограниченный ответ исчерпывает ресурсы, а неопределённый порядок делает обход коллекции невоспроизводимым.

Проверка

  • contract-тест границ размера и порядка;
  • тест конкурентного изменения коллекции;
  • security-тест подмены маркера продолжения.

Исключения

Непагинированный ответ допустим только для множества с доказуемой и автоматически проверяемой верхней границей.

BE-HTTP-005. Машинно-проверяемый контракт

Уровень: MUST

Применяется к: каждому опубликованному HTTP endpoint

Метод, path template, параметры, headers, media types, схема тела, статусы ответа и схема ошибки должны быть описаны в версионируемом машинно-проверяемом контракте. Неподдерживаемый media type должен отклоняться, а не определяться по содержимому. Реализация и создаваемый client должны проверяться относительно одной версии контракта.

Обоснование

Текстовое описание не позволяет доказать соответствие реализации и consumer.

Проверка

  • syntax и schema validation контракта;
  • contract-тест реализации;
  • повторная генерация client зафиксированным генератором.

Исключения

Внутрипроцессный HTTP adapter, недоступный другому компоненту, не является опубликованным endpoint.

BE-HTTP-006. Семантика метода и статуса

Уровень: MUST

Применяется к: каждой операции HTTP API

Контракт должен использовать семантику HTTP-метода и статуса без скрытого изменения состояния через объявленную безопасной операцию. Успех создания, асинхронного принятия, отсутствующего тела и частичного ответа должен различаться статусом и схемой. Consumer не должен определять успех только по наличию тела.

Обоснование

Промежуточные компоненты и consumers опираются на стандартную семантику метода и статуса.

Проверка

  • contract-тест каждого статуса;
  • тест отсутствующего тела;
  • review safe и idempotent операций.

Исключения

Legacy-контракт требует ограниченного ADR и не должен распространяться на новые операции.

BE-HTTP-007. Валидация до выполнения

Уровень: MUST

Применяется к: path, query, headers и телу входящего запроса

Сервер должен до прикладного эффекта проверять тип, формат, диапазон, длину, обязательность и допустимые неизвестные поля согласно контракту. Отсутствие значения должно отличаться от пустого, нулевого и фиктивного. Невалидный запрос не должен частично изменять состояние.

Обоснование

Поздняя или неполная валидация переносит недоверенные данные во внутреннюю модель и оставляет частичный эффект.

Проверка

  • generated boundary tests из схемы;
  • property-based тест parser;
  • тест отсутствия эффекта при каждом классе ошибки.

Исключения

Потоковый body может проверяться по частям, если ни одна часть не становится доступной как успешный результат до проверки применимых инвариантов.

BE-HTTP-010. Конкурентное изменение ресурса

Уровень: MUST

Применяется к: операции, способной перезаписать конкурентное изменение

Контракт должен принимать версию ресурса, precondition или эквивалентный идентификатор состояния и возвращать стабильный конфликт при устаревшем входе. Неусловное last-write-wins не должно применяться без явно объявленной семантики.

Обоснование

Идемпотентность повтора не предотвращает потерю независимого конкурентного изменения.

Проверка

  • конкурентный contract-тест двух клиентов;
  • тест устаревшей precondition;
  • тест повторной отправки одного изменения.

Исключения

Last-write-wins допустим для поля, где это прямо определено контрактом и подтверждено тестом.

BE-HTTP-011. Контракт ограничения частоты

Уровень: MUST

Применяется к: HTTP endpoint с ограничением частоты или квотой запросов

Контракт должен определять единицу учитываемой операции, доверенный источник ключа ограничения, временную модель, численный предел, допустимый burst и область действия: субъект, credential, tenant, client либо сетевой источник. Значение заголовка или query, непосредственно контролируемое недоверенным клиентом, не должно само считаться identity ограничения.

Отклонённый запрос не должен создавать прикладной эффект и должен возвращать 429 Too Many Requests, стабильный код ошибки по BE-HTTP-002 и Retry-After, если сервер может определить минимальный срок следующей попытки. Ограничение должно действовать на объявленную область суммарно по одновременно обслуживающим экземплярам. При недоступности механизма должны быть заранее определены fail-open, fail-closed или ограниченный локальный режим и наблюдаемый результат для клиента.

Обоснование

Необъявленный ключ позволяет обходить лимит, а независимый local counter умножает допустимый трафик при масштабировании и неопределённо ведёт себя при отказе.

Проверка

  • contract-тест границы, burst, 429 и Retry-After;
  • конкурентный нагрузочный тест через несколько экземпляров;
  • security-тест подмены identity ограничения;
  • тест недоступности общего состояния rate limiter.

Исключения

Заранее ограниченный upstream MAY не применять отдельный rate limit, если граница и её максимальная ёмкость проверены. Endpoint без ограничения находится вне области требования.