Ответ
Метод GET в HTTP/1.1 определен RFC 7231 и имеет несколько ключевых ограничений, связанных с его семантикой и безопасностью.
1. Семантическое ограничение: «Безопасность» (Safe)
- Правило: GET запросы должны быть идемпотентными и безопасными. Это означает, что они не должны изменять состояние сервера.
- Почему: Позволяет кешированию, индексации поисковыми системами, безопасной перезагрузке страницы в браузере.
- Нарушение (антипаттерн):
GET /users/delete?id=123 HTTP/1.1Удаление через GET — грубое нарушение контракта метода.
2. Ограничение на передачу данных
- Правило: Данные передаются только в URL (как query-параметры или часть пути). У запроса нет тела (entity-body).
- Следствие:
- Ограничение длины: Максимальная длина URL определяется браузером (обычно ~2000 символов) и сервером (настраивается, например, в nginx
large_client_header_buffers). - Видимость данных: Параметры видны в истории браузера, логах, referrer.
- Типы данных: Сложно передавать структурированные данные (например, JSON).
- Ограничение длины: Максимальная длина URL определяется браузером (обычно ~2000 символов) и сервером (настраивается, например, в nginx
3. Кешируемость (Cacheable)
- Правило: Ответы на GET запросы по умолчанию считаются кешируемыми.
- Следствие: Это ограничение для разработчика — если ответ не должен кешироваться, необходимо явно использовать заголовки
Cache-Control: no-store.
4. Идемпотентность
- Правило: Многократное выполнение одного и того же GET запроса должно давать одинаковый результат (при условии, что состояние ресурса на сервере не менялось другими способами).
Практический пример сравнения GET и POST:
// GET: Для получения данных. Параметры в URL.
GET /api/search?query=spring&limit=10 HTTP/1.1
Host: example.com
// POST: Для отправки данных на создание/обработку. Параметры в теле.
POST /api/users HTTP/1.1
Host: example.com
Content-Type: application/json
{"name": "John", "email": "john@example.com"}
Вывод: Используйте GET только для операций чтения (получения представлений ресурсов). Для любых действий, изменяющих данные (создание, обновление, удаление), используйте POST, PUT, PATCH или DELETE.