Пошук уроків, статей та іншого контенту
Вивчимо GET, POST, PUT, PATCH, DELETE та інші HTTP-методи й визначимо їхнє призначення.
HTTP-метод визначає, яку дію клієнт хоче виконати над ресурсом на сервері.
Наприклад, ресурсом може бути користувач:
/users
/users/42Клієнт надсилає HTTP-запит, у якому вказує:
метод;
URL;
заголовки;
за потреби — тіло запиту.
Приклад запиту:
GET /users/42 HTTP/1.1
Host: example.comУ цьому запиті:
GET — HTTP-метод;
/users/42 — адреса ресурсу;
Host — заголовок запиту.
Методи не обмежуються назвами URL. Саме метод пояснює, що клієнт хоче зробити: отримати дані, створити ресурс, змінити його або видалити.
Метод GET використовується для отримання даних.
Приклади:
GET /users
GET /users/42
GET /products?category=booksGET /users — отримати список користувачів;
GET /users/42 — отримати користувача з ідентифікатором 42;
GET /products?category=books — отримати товари з певною категорією.
Запит GET зазвичай не має тіла. Параметри для фільтрації або пошуку передаються в URL після символу ?.
Важливо: GET не повинен змінювати дані на сервері. Повторне виконання такого запиту має лише повертати результат.
Метод POST використовується для створення нового ресурсу або передавання даних на обробку.
Приклад:
POST /users HTTP/1.1
Content-Type: application/json
{
"name": "Олена",
"email": "olena@example.com"
}У цьому випадку клієнт просить сервер створити нового користувача.
Інший приклад:
POST /users/42/commentsТакий запит може створювати коментар для користувача з ідентифікатором 42.
POST часто містить тіло запиту. Формат тіла визначається заголовком Content-Type, наприклад:
Content-Type: application/jsonМетод PUT використовується для повної заміни ресурсу або створення ресурсу за конкретною адресою.
Приклад:
PUT /users/42 HTTP/1.1
Content-Type: application/json
{
"name": "Олена",
"email": "new-email@example.com"
}Такий запит означає: замінити ресурс /users/42 переданими даними.
Якщо ресурс має кілька властивостей, під час повної заміни зазвичай потрібно передати всі необхідні властивості.
PUT є ідемпотентним методом. Це означає, що повторення одного й того самого запиту приводить до того самого результату:
PUT /users/42 з однаковими даними
PUT /users/42 з однаковими данимиПісля першого запиту ресурс зміниться, а наступні запити встановлять йому ті самі значення.
Метод PATCH використовується для часткової зміни ресурсу.
Приклад:
PATCH /users/42 HTTP/1.1
Content-Type: application/json
{
"email": "new-email@example.com"
}У цьому випадку змінюється лише email. Інші властивості користувача залишаються без змін.
Різниця між PUT і PATCH:
PUT — повністю замінює ресурс;
PATCH — змінює лише передані частини ресурсу.
Наприклад, якщо користувач має такі дані:
{
"name": "Олена",
"email": "olena@example.com",
"role": "user"
}Після запиту:
PUT /users/42
{
"name": "Олена"
}частина даних може бути замінена або втрачена, залежно від реалізації сервера.
Після запиту:
PATCH /users/42
{
"name": "Олена"
}зазвичай зміниться лише name.
Метод DELETE використовується для видалення ресурсу.
Приклад:
DELETE /users/42Сервер може видалити користувача з ідентифікатором 42.
Запит DELETE зазвичай не має тіла, але протокол не забороняє його використовувати. Конкретна поведінка залежить від API.
HEAD працює подібно до GET, але сервер повертає лише заголовки без тіла відповіді.
Приклад:
HEAD /users/42Такий запит може допомогти перевірити:
чи існує ресурс;
розмір відповіді;
тип даних;
дату останньої зміни.
OPTIONS повідомляє, які можливості підтримує ресурс або сервер.
Приклад:
OPTIONS /usersСервер може відповісти заголовком:
Allow: GET, POST, OPTIONSЦе означає, що для цього ресурсу підтримуються методи GET, POST і OPTIONS.
Метод OPTIONS також використовується браузерами під час деяких кросдоменних запитів.
TRACE використовується для діагностики маршруту HTTP-запиту. Сервер може повернути отриманий запит назад клієнту.
У прикладних API цей метод майже не використовують. З міркувань безпеки сервери часто його вимикають.
CONNECT встановлює тунель до сервера. Найчастіше він використовується проксі-серверами для створення захищеного з'єднання HTTPS.
У звичайних Node.js API цей метод зазвичай не потрібен.
HTTP-методи часто пов'язують з операціями CRUD:
| CRUD-операція | HTTP-метод | Приклад | |---|---|---| | Create — створити | POST | POST /users | | Read — прочитати | GET | GET /users/42 | | Update — оновити | PUT або PATCH | PATCH /users/42 | | Delete — видалити | DELETE | DELETE /users/42 |
Наприклад, API для роботи з користувачами може мати такі маршрути:
GET /users отримати всіх користувачів
GET /users/42 отримати одного користувача
POST /users створити користувача
PUT /users/42 повністю замінити користувача
PATCH /users/42 частково змінити користувача
DELETE /users/42 видалити користувачаОдна й та сама адреса може використовуватися з різними методами, тому що метод визначає дію:
GET /users/42 отримати користувача
PATCH /users/42 змінити користувача
DELETE /users/42 видалити користувачаNode.js має вбудований модуль node:http, тому для простого прикладу не потрібні додаткові бібліотеки.
Створімо файл server.js:
const http = require('node:http');
const users = [
{ id: 1, name: 'Олена' },
{ id: 2, name: 'Андрій' },
];
function sendJson(response, statusCode, data) {
response.writeHead(statusCode, {
'Content-Type': 'application/json; charset=utf-8',
});
response.end(JSON.stringify(data));
}
function readRequestBody(request) {
return new Promise((resolve, reject) => {
let body = '';
request.on('data', (chunk) => {
body += chunk;
});
request.on('end', () => {
if (body === '') {
resolve({});
return;
}
try {
resolve(JSON.parse(body));
} catch {
reject(new Error('Некоректний JSON'));
}
});
request.on('error', reject);
});
}
const server = http.createServer(async (request, response) => {
const url = new URL(request.url, `http://${request.headers.host}`);
const method = request.method;
if (url.pathname === '/users' && method === 'GET') {
sendJson(response, 200, users);
return;
}
if (url.pathname === '/users' && method === 'POST') {
try {
const body = await readRequestBody(request);
if (typeof body.name !== 'string' || body.name.trim() === '') {
sendJson(response, 400, { error: 'Поле name є обов’язковим' });
return;
}
const user = {
id: users.length + 1,
name: body.name,
};
users.push(user);
sendJson(response, 201, user);
} catch {
sendJson(response, 400, { error: 'Некоректний JSON' });
}
return;
}
const userMatch = url.pathname.match(/^\/users\/(\d+)$/);
if (userMatch) {
const userId = Number(userMatch[1]);
const userIndex = users.findIndex((user) => user.id === userId);
if (userIndex === -1) {
sendJson(response, 404, { error: 'Користувача не знайдено' });
return;
}
if (method === 'GET') {
sendJson(response, 200, users[userIndex]);
return;
}
if (method === 'PATCH') {
try {
const body = await readRequestBody(request);
if (typeof body.name === 'string' && body.name.trim() !== '') {
users[userIndex].name = body.name;
}
sendJson(response, 200, users[userIndex]);
} catch {
sendJson(response, 400, { error: 'Некоректний JSON' });
}
return;
}
if (method === 'DELETE') {
const deletedUser = users.splice(userIndex, 1)[0];
sendJson(response, 200, deletedUser);
return;
}
}
sendJson(response, 404, { error: 'Маршрут не знайдено' });
});
server.listen(3000, () => {
console.log('Сервер запущено на http://localhost:3000');
});Запустіть сервер:
node server.jsТепер можна виконати запити з іншого термінала.
Отримати всіх користувачів:
curl http://localhost:3000/usersОтримати одного користувача:
curl http://localhost:3000/users/1Створити користувача:
curl -X POST http://localhost:3000/users \
-H "Content-Type: application/json" \
-d '{"name":"Марія"}'Частково змінити користувача:
curl -X PATCH http://localhost:3000/users/1 \
-H "Content-Type: application/json" \
-d '{"name":"Олена Коваль"}'Видалити користувача:
curl -X DELETE http://localhost:3000/users/2У прикладі:
GET /users повертає список;
GET /users/:id повертає одного користувача;
POST /users створює користувача;
PATCH /users/:id змінює його ім'я;
DELETE /users/:id видаляє користувача.
Тіло запиту найчастіше використовують із POST, PUT і PATCH.
Наприклад:
PATCH /users/1 HTTP/1.1
Content-Type: application/json
{
"name": "Нове ім'я"
}Щоб сервер правильно прочитав JSON, потрібні дві умови:
клієнт передає заголовок Content-Type: application/json;
тіло містить коректний JSON.
Методи GET і DELETE зазвичай використовують без тіла. Дані для таких запитів часто передаються в URL:
GET /users?role=admin
DELETE /users/42HTTP-метод визначає дію, а код стану повідомляє результат цієї дії.
Поширені коди:
200 OK — запит успішно виконано;
201 Created — ресурс успішно створено;
204 No Content — запит успішний, але тіло відповіді відсутнє;
400 Bad Request — запит має неправильний формат;
404 Not Found — ресурс або маршрут не знайдено;
405 Method Not Allowed — маршрут існує, але не підтримує вказаний метод;
500 Internal Server Error — внутрішня помилка сервера.
Наприклад, успішний POST часто повертає 201:
HTTP/1.1 201 Created
Content-Type: application/jsonЯкщо користувача не знайдено для GET, PATCH або DELETE, сервер зазвичай повертає 404.
Метод називають безпечним, якщо його виконання не повинно змінювати стан сервера.
Безпечними є:
GET;
HEAD;
OPTIONS;
TRACE.
Метод називають ідемпотентним, якщо повторення однакового запиту має такий самий запланований результат, як і одне виконання.
Зазвичай ідемпотентними вважають:
GET;
HEAD;
PUT;
DELETE;
OPTIONS;
TRACE.
POST зазвичай не є ідемпотентним. Наприклад, два однакові запити:
POST /usersможуть створити двох різних користувачів.
Ці властивості важливі для повторних спроб запиту, кешування та роботи мережевих посередників.
Поганий варіант:
GET /users/42/deleteGET призначений для отримання даних. Для видалення потрібно використовувати:
DELETE /users/42Так сервери, браузери та інші клієнти краще розуміють призначення запиту.
Якщо потрібно змінити лише одне поле, зазвичай використовують PATCH.
PATCH /users/42Якщо потрібно передати повний новий стан ресурсу, використовують PUT.
PUT /users/42Точна поведінка залежить від API, але таке розділення робить його зрозумілішим.
Якщо клієнт передає JSON без заголовка:
Content-Type: application/jsonсервер може не зрозуміти формат тіла запиту.
Маршрут може підтримувати лише певні методи. Наприклад, сервер може дозволяти:
GET /users
POST /usersале не дозволяти:
DELETE /usersУ такому випадку потрібно повернути 405 Method Not Allowed, а не обробляти запит як звичайний GET.
Для POST, PUT і PATCH сервер має прочитати тіло запиту, перевірити його формат і дані. Не можна без перевірки використовувати будь-яке значення від клієнта.
HTTP-метод описує дію клієнта над ресурсом.
GET отримує дані.
POST створює ресурс або передає дані на обробку.
PUT повністю замінює ресурс.
PATCH частково змінює ресурс.
DELETE видаляє ресурс.
HEAD повертає заголовки без тіла.
OPTIONS показує підтримувані можливості ресурсу.
Методи можна комбінувати з однаковим маршрутом, наприклад GET, PATCH і DELETE для /users/42.
Для даних у форматі JSON потрібно використовувати Content-Type: application/json.
HTTP-метод і код відповіді виконують різні ролі: метод описує дію, а код — результат.