CRUD и HTTP-методы
CRUD (Create, Read, Update, Delete) — четыре базовые операции над данными, которые в REST API реализуются соответствующими HTTP-методами.
Зачем нужно
Понимание маппинга CRUD на HTTP-методы — фундамент проектирования REST API. Правильный выбор метода делает API предсказуемым, позволяет браузерам и прокси кэшировать ответы, а клиентам — строить запросы по очевидным соглашениям.
Где используется
- Проектирование REST-эндпоинтов бэкенда
- Реализация CRUD в Express, Fastify, NestJS
- Написание клиентских fetch-запросов с правильными методами
- Документирование API в OpenAPI/Swagger
CRUD ↔ HTTP маппинг
| CRUD | HTTP метод | Идемпотентный | Безопасный | Пример URL |
|---|---|---|---|---|
| Create | POST | нет | нет | POST /api/users |
| Read | GET | да | да | GET /api/users/42 |
| Update (полное) | PUT | да | нет | PUT /api/users/42 |
| Update (частичное) | PATCH | нет* | нет | PATCH /api/users/42 |
| Delete | DELETE | да | нет | DELETE /api/users/42 |
* PATCH может быть идемпотентным — зависит от реализации.
Примеры запросов
# CREATE — создать пользователя
POST /api/users HTTP/1.1
Content-Type: application/json
{"name": "Антон", "email": "anton@example.com"}
# → 201 Created
# Location: /api/users/42
# READ — получить список
GET /api/users?page=1&limit=20 HTTP/1.1
# → 200 OK
# [{"id": 1, "name": "..."}, ...]
# READ — один объект
GET /api/users/42 HTTP/1.1
# → 200 OK или 404 Not Found
# UPDATE (полное) — заменить весь объект
PUT /api/users/42 HTTP/1.1
Content-Type: application/json
{"name": "Антон", "email": "new@example.com", "role": "admin"}
# → 200 OK
# UPDATE (частичное) — изменить только email
PATCH /api/users/42 HTTP/1.1
Content-Type: application/json
{"email": "new@example.com"}
# → 200 OK
# DELETE
DELETE /api/users/42 HTTP/1.1
# → 204 No Content
Реализация на fetch
const BASE = 'https://api.example.com';
// Create
async function createUser(data) {
const res = await fetch(`${BASE}/users`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data),
});
if (!res.ok) throw new Error(res.statusText);
return res.json(); // 201
}
// Read
async function getUser(id) {
const res = await fetch(`${BASE}/users/${id}`);
if (res.status === 404) return null;
return res.json();
}
// Update (PATCH)
async function patchUser(id, changes) {
const res = await fetch(`${BASE}/users/${id}`, {
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(changes),
});
return res.json();
}
// Delete
async function deleteUser(id) {
const res = await fetch(`${BASE}/users/${id}`, { method: 'DELETE' });
return res.status === 204;
}
Частые ошибки
- Использование POST для всех операций вместо GET/PUT/DELETE
- PUT без передачи полного объекта — забытые поля становятся
null - Возврат 200 при удалении вместо 204 No Content
- Путаница PUT и PATCH: PUT заменяет объект целиком, PATCH — частично
- GET-запросы с телом (body) — нарушает спецификацию и ломает кэши
Связанные темы
- _MOC Сеть
- REST API
- HTTP-методы -- GET, POST, PUT, DELETE, PATCH
- Протокол HTTP -- основы
- Тело запроса и ответа
- Пагинация и фильтрация