Можно ли передавать тело (body) в HTTP GET-запросе?

«Можно ли передавать тело (body) в HTTP GET-запросе?» — вопрос из категории HTTP и веб-протоколы, который задают на 24% собеседований AQA / Automation. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Технически, спецификация HTTP (RFC 7231) не запрещает наличие тела у GET-запроса, но и не определяет его семантику. На практике это считается плохой практикой и приводит к проблемам.

Почему этого следует избегать в тестировании и разработке:

  1. Непредсказуемость: Многие компоненты не ожидают тело у GET и могут его проигнорировать или отбросить.

    • Серверы: Nginx, некоторые версии Apache по умолчанию отбрасывают тело GET.
    • Прокси-серверы и кэширующие серверы могут не учитывать тело при кэшировании, что приведет к некорректным ответам.
    • Библиотеки и инструменты: Многие клиентские библиотеки (например, старые версии requests в Python) могут не поддерживать эту возможность.
  2. Нарушение семантики: GET предназначен для получения (fetch) ресурсов. Данные для идентификации ресурса должны передаваться в URL (через path или query-параметры). Для операций, отправляющих данные, используйте POST, PUT или PATCH.

Правильный подход для тестирования API:

# НЕПРАВИЛЬНО (рискованно):
GET /api/users HTTP/1.1
Content-Type: application/json

{"filter": "active"}

# ПРАВИЛЬНО (использовать query-параметры):
GET /api/users?filter=active HTTP/1.1

# ИЛИ ПРАВИЛЬНО (если запрос сложный, использовать POST):
POST /api/users/_search HTTP/1.1  # Часто используется эндпоинт "_search" или "query"
Content-Type: application/json

{"filter": {"status": "active", "age": {"$gt": 30}}}

При написании автотестов для API всегда следуйте документации API. Если вы столкнулись с GET-запросом с телом, это красный флаг, который стоит обсудить с разработчиками.