HTTP-методы: GET, POST, PUT, DELETE, PATCH

HTTP-методы (или HTTP-глаголы) определяют намерение клиента: что именно он хочет сделать с ресурсом на сервере — получить, создать, обновить или удалить.

Зачем нужно

Правильный выбор метода — основа RESTful API дизайна. Метод влияет на поведение браузера (GET кешируется, POST нет), промежуточных прокси, идемпотентность операций и семантику API. Неправильное использование (DELETE через GET, создание через GET) нарушает REST-соглашения и создаёт проблемы с безопасностью.

Где используется

  • REST API — CRUD операции
  • Браузерные формы (поддерживают только GET и POST)
  • fetch/axios запросы с любым методом
  • GraphQL (обычно POST)

Основной контент

Методы и их семантика

Метод Семантика Тело запроса Идемпотентный Безопасный
GET Получить ресурс Нет Да Да
POST Создать ресурс Да Нет Нет
PUT Заменить ресурс целиком Да Да Нет
PATCH Частично обновить Да Нет* Нет
DELETE Удалить ресурс Необязательно Да Нет
HEAD Заголовки без тела Нет Да Да
OPTIONS Preflight CORS Нет Да Да

*Идемпотентность PATCH зависит от реализации

GET — получить ресурс

// Запрос
GET /api/users?page=1&limit=10 HTTP/1.1

// Express
app.get('/api/users', async (req, res) => {
  const users = await UserService.getAll(req.query);
  res.json(users);
});

// Клиент
const response = await fetch('/api/users?page=1');
const users = await response.json();

POST — создать ресурс

// Запрос
POST /api/users HTTP/1.1
Content-Type: application/json

{ "name": "Alice", "email": "alice@example.com" }

// Express
app.post('/api/users', async (req, res) => {
  const user = await UserService.create(req.body);
  res
    .status(201)
    .set('Location', `/api/users/${user.id}`)
    .json(user);
});

PUT — полная замена ресурса

// Запрос — ВСЕГДА передаём полный объект
PUT /api/users/42 HTTP/1.1
{ "name": "Alice Updated", "email": "alice@example.com", "role": "admin" }

// Express
app.put('/api/users/:id', async (req, res) => {
  // req.body должен содержать ВСЕ поля ресурса
  const user = await UserService.replace(req.params.id, req.body);
  res.json(user);
});

PATCH — частичное обновление

// Запрос — только изменяемые поля
PATCH /api/users/42 HTTP/1.1
{ "name": "Alice New Name" }

// Express
app.patch('/api/users/:id', async (req, res) => {
  const user = await UserService.update(req.params.id, req.body);
  res.json(user);
});

DELETE — удалить ресурс

// Запрос
DELETE /api/users/42 HTTP/1.1

// Express
app.delete('/api/users/:id', async (req, res) => {
  await UserService.delete(req.params.id);
  res.status(204).send; // No Content
});

HEAD и OPTIONS

// HEAD — как GET, но без тела (проверить существование, размер файла)
app.head('/api/users/:id', async (req, res) => {
  const exists = await UserService.exists(req.params.id);
  res.status(exists ? 200 : 404).send;
});

// OPTIONS — автоматически обрабатывается CORS middleware
// Браузер делает preflight OPTIONS перед CORS-запросом

REST-соглашения

GET    /users          → список
GET    /users/42       → один пользователь
POST   /users          → создать
PUT    /users/42       → заменить
PATCH  /users/42       → обновить
DELETE /users/42       → удалить

GET    /users/42/posts → посты пользователя (nested resource)
POST   /users/42/posts → создать пост у пользователя

Частые ошибки

  • GET с побочными эффектами — GET должен быть безопасным (safe): не изменять данные. Браузер может кешировать и повторить GET-запрос
  • PUT вместо PATCH — PUT заменяет весь ресурс: если забыть поле, оно удалится; PATCH — только указанные поля
  • POST для всего — нарушает REST-семантику и ломает идемпотентность
  • DELETE возвращает тело — REST-соглашение: DELETE → 204 No Content без тела

Связанные темы

Ресурсы