Антон Ларичев

Введение
Каждый раз, когда браузер запрашивает страницу или мобильное приложение обращается к серверу, используется один из HTTP методов. GET, POST, PUT и DELETE — это не просто слова в документации: от правильного выбора метода зависит, насколько ваш API будет предсказуемым, безопасным и понятным другим разработчикам.
В этой статье разберём каждый метод на практических примерах, объясним понятие идемпотентности и покажем типичные ошибки, которые допускают при проектировании REST API.
Что такое HTTP метод
HTTP метод (иногда называют «глагол») указывает серверу, какое действие нужно выполнить над ресурсом. Ресурс — это любая сущность, доступная по URL: пользователь, статья, заказ, файл.
Стандарт HTTP/1.1 определяет несколько методов, но в повседневной веб-разработке чаще всего используются четыре: GET, POST, PUT и DELETE.
Метод GET
GET используется для получения данных. Он не изменяет состояние сервера — только читает.
GET /api/users/42 HTTP/1.1
Host: example.com
Пример на JavaScript с использованием fetch:
// Получаем данные пользователя по ID
const response = await fetch('/api/users/42');
const user = await response.json();
console.log(user.name);
Важные свойства GET:
- Параметры передаются в строке запроса (query string):
/api/users?role=admin&page=2 - Запросы кешируются браузером и прокси-серверами
- Не используется для передачи чувствительных данных — URL попадает в логи
- Безопасен и идемпотентен (об этом подробнее ниже)
Метод POST
POST создаёт новый ресурс или отправляет данные для обработки. Данные передаются в теле запроса.
POST /api/users HTTP/1.1
Host: example.com
Content-Type: application/json
{"name": "Иван", "email": "ivan@example.com"}
Пример создания пользователя:
// Создаём нового пользователя
const response = await fetch('/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: 'Иван', email: 'ivan@example.com' })
});
// Сервер возвращает созданного пользователя с присвоенным ID
const newUser = await response.json();
console.log(newUser.id); // например, 43
Сервер обычно отвечает статусом 201 Created и возвращает созданный ресурс в теле ответа. POST не идемпотентен: два одинаковых запроса создадут два разных ресурса.
Метод PUT
PUT полностью заменяет существующий ресурс. Если ресурса не существует, некоторые реализации создают его.
PUT /api/users/42 HTTP/1.1
Host: example.com
Content-Type: application/json
{"name": "Иван Петров", "email": "ivan@example.com", "role": "admin"}
Пример полного обновления:
// Полностью заменяем данные пользователя
const response = await fetch('/api/users/42', {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
name: 'Иван Петров',
email: 'ivan@example.com',
role: 'admin'
})
});
Ключевое отличие от PATCH: PUT требует передачи полного объекта. Если не передать поле role, оно будет обнулено или удалено.
Метод PATCH
PATCH — частичное обновление ресурса. Передаёте только те поля, которые нужно изменить:
// Обновляем только имя, остальные поля не трогаем
const response = await fetch('/api/users/42', {
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: 'Иван Петров' })
});
Метод DELETE
DELETE удаляет ресурс по указанному URL.
DELETE /api/users/42 HTTP/1.1
Host: example.com
Пример удаления:
// Удаляем пользователя с ID 42
const response = await fetch('/api/users/42', {
method: 'DELETE'
});
if (response.status === 204) {
// 204 No Content — удаление прошло успешно, тело пустое
console.log('Пользователь удалён');
}
Сервер обычно возвращает 204 No Content (без тела) или 200 OK с подтверждающим сообщением.
Идемпотентность и безопасность
Эти два понятия помогают понять поведение методов при повторных запросах.
Безопасный метод не изменяет состояние сервера. GET и HEAD — безопасные методы.
Идемпотентный метод при повторном выполнении с теми же параметрами даёт тот же результат. GET, PUT и DELETE — идемпотентны.
| Метод | Безопасный | Идемпотентный |
|---|---|---|
| GET | Да | Да |
| POST | Нет | Нет |
| PUT | Нет | Да |
| PATCH | Нет | Нет* |
| DELETE | Нет | Да |
*PATCH может быть идемпотентным, зависит от реализации.
Практический смысл: если запрос потерялся в сети, клиент может безопасно повторить GET, PUT или DELETE. Повторять POST без проверки нельзя — рискуете создать дубликат.
Частые ошибки
Ошибка 1: Использование GET для изменения данных
// Неправильно — GET не должен изменять состояние
fetch('/api/users/42/delete');
// Правильно
fetch('/api/users/42', { method: 'DELETE' });
Ошибка 2: Передача чувствительных данных в GET-параметрах
// Неправильно — пароль виден в URL, логах, истории браузера
GET /api/login?password=secret123
// Правильно — используем POST с телом запроса
POST /api/login
{"password": "secret123"}
Ошибка 3: Использование POST вместо PUT/PATCH для обновлений
// Неправильно — POST для обновления нарушает семантику REST
fetch('/api/users/update', {
method: 'POST',
body: JSON.stringify({ id: 42, name: 'Новое имя' })
});
// Правильно — PATCH для частичного обновления
fetch('/api/users/42', {
method: 'PATCH',
body: JSON.stringify({ name: 'Новое имя' })
});
Ошибка 4: Игнорирование кодов ответа
Метод и код ответа работают в паре. POST при успехе возвращает 201, DELETE — 204, GET — 200. Возвращать 200 на всё подряд — распространённая ошибка, которая усложняет отладку.
Заключение
Правильный выбор HTTP метода делает API читаемым и предсказуемым. Используйте GET для чтения, POST для создания, PUT/PATCH для обновления и DELETE для удаления — и ваш API будет соответствовать ожиданиям любого разработчика, который с ним работает.
Понимание идемпотентности помогает строить надёжные системы: клиенты знают, какие запросы безопасно повторять при сетевых сбоях. Это особенно важно при проектировании микросервисов и распределённых систем, где потери пакетов — норма, а не исключение.






Комментарии
0