Пошук уроків, статей та іншого контенту
Реалізуєте операції створення, читання, оновлення та видалення ресурсів у повноцінному REST API.
CRUD — це чотири базові операції над ресурсами:
Create — створення ресурсу;
Read — отримання ресурсу або списку ресурсів;
Update — оновлення ресурсу;
Delete — видалення ресурсу.
У REST API ці операції зазвичай відповідають HTTP-методам:
| Операція | HTTP-метод | Приклад маршруту | |---|---|---| | Створення | POST | /tasks | | Отримання списку | GET | /tasks | | Отримання одного ресурсу | GET | /tasks/1 | | Оновлення | PUT | /tasks/1 | | Видалення | DELETE | /tasks/1 |
У цьому уроці створимо API для керування завданнями.
Створіть нову папку та ініціалізуйте Node.js-проєкт:
mkdir crud-api
cd crud-api
npm init -y
npm install expressСтворіть файл server.js.
Для зберігання даних використаємо масив у пам’яті. Це зручно для навчання, але після перезапуску сервера всі дані повернуться до початкових.
const express = require('express');
const app = express();
const PORT = 3000;
// Дозволяє серверу читати JSON у тілі запитів
app.use(express.json());
let nextId = 3;
let tasks = [
{
id: 1,
title: 'Вивчити Node.js',
completed: false
},
{
id: 2,
title: 'Створити REST API',
completed: true
}
];
// Отримання всіх завдань
app.get('/tasks', (req, res) => {
res.status(200).json(tasks);
});
// Отримання одного завдання
app.get('/tasks/:id', (req, res) => {
const id = Number.parseInt(req.params.id, 10);
const task = tasks.find((item) => item.id === id);
if (!task) {
return res.status(404).json({
error: 'Завдання не знайдено'
});
}
res.status(200).json(task);
});
// Створення завдання
app.post('/tasks', (req, res) => {
const { title } = req.body;
if (typeof title !== 'string' || title.trim() === '') {
return res.status(400).json({
error: 'Поле title є обов’язковим'
});
}
const newTask = {
id: nextId,
title: title.trim(),
completed: false
};
nextId += 1;
tasks.push(newTask);
res.status(201).json(newTask);
});
// Повне оновлення завдання
app.put('/tasks/:id', (req, res) => {
const id = Number.parseInt(req.params.id, 10);
const taskIndex = tasks.findIndex((item) => item.id === id);
if (taskIndex === -1) {
return res.status(404).json({
error: 'Завдання не знайдено'
});
}
const { title, completed } = req.body;
if (
typeof title !== 'string' ||
title.trim() === '' ||
typeof completed !== 'boolean'
) {
return res.status(400).json({
error: 'Поля title та completed мають бути правильного типу'
});
}
const updatedTask = {
id,
title: title.trim(),
completed
};
tasks[taskIndex] = updatedTask;
res.status(200).json(updatedTask);
});
// Видалення завдання
app.delete('/tasks/:id', (req, res) => {
const id = Number.parseInt(req.params.id, 10);
const taskIndex = tasks.findIndex((item) => item.id === id);
if (taskIndex === -1) {
return res.status(404).json({
error: 'Завдання не знайдено'
});
}
tasks.splice(taskIndex, 1);
res.status(204).send();
});
// Обробка невідомих маршрутів
app.use((req, res) => {
res.status(404).json({
error: 'Маршрут не знайдено'
});
});
app.listen(PORT, () => {
console.log(`Сервер запущено: http://localhost:${PORT}`);
});Запустіть сервер:
node server.jsПісля цього API буде доступне за адресою:
http://localhost:3000Виконайте GET-запит:
curl http://localhost:3000/tasksВідповідь:
[
{
"id": 1,
"title": "Вивчити Node.js",
"completed": false
},
{
"id": 2,
"title": "Створити REST API",
"completed": true
}
]Сервер повертає статус 200 OK, коли список успішно отримано.
Для отримання ресурсу за ідентифікатором використовується параметр маршруту :id:
curl http://localhost:3000/tasks/1Відповідь:
{
"id": 1,
"title": "Вивчити Node.js",
"completed": false
}Якщо завдання не існує, сервер повертає 404 Not Found:
{
"error": "Завдання не знайдено"
}req.params.id містить значення параметра маршруту. Оскільки параметри маршруту є рядками, його потрібно перетворити на число:
const id = Number.parseInt(req.params.id, 10);Для створення завдання використовується POST /tasks. Дані передаються в тілі запиту у форматі JSON:
curl -X POST http://localhost:3000/tasks \
-H "Content-Type: application/json" \
-d "{\"title\":\"Написати тести\"}"Сервер створить нове завдання:
{
"id": 3,
"title": "Написати тести",
"completed": false
}Для успішного створення ресурсу використовується статус 201 Created.
Middleware:
app.use(express.json());перетворює JSON із тіла запиту на JavaScript-об’єкт, доступний через req.body.
Наприклад, для такого запиту:
{
"title": "Написати тести"
}можна отримати значення властивості:
const { title } = req.body;Перед створенням ресурсу сервер перевіряє, що title є непорожнім рядком. Якщо дані неправильні, повертається статус 400 Bad Request.
У прикладі для повного оновлення використовується метод PUT. Клієнт має передати всі поля, які потрібні для оновленого ресурсу:
curl -X PUT http://localhost:3000/tasks/1 \
-H "Content-Type: application/json" \
-d "{\"title\":\"Вивчити Express\",\"completed\":true}"Відповідь:
{
"id": 1,
"title": "Вивчити Express",
"completed": true
}Метод PUT замінює ресурс новою версією. Тому сервер перевіряє і title, і completed.
Якщо завдання з таким ідентифікатором не існує, повертається 404 Not Found.
Для видалення використовується метод DELETE:
curl -X DELETE http://localhost:3000/tasks/2Після успішного видалення сервер повертає статус 204 No Content.
Цей статус означає, що операція виконана успішно, але тіло відповіді відсутнє. Саме тому в коді використовується:
res.status(204).send();У CRUD API важливо повертати статус, який описує результат операції:
200 OK — успішне отримання або оновлення;
201 Created — ресурс успішно створено;
204 No Content — ресурс успішно видалено, тіло відповіді відсутнє;
400 Bad Request — клієнт передав некоректні дані;
404 Not Found — ресурс або маршрут не знайдено.
Статус можна встановити методом res.status():
res.status(404).json({
error: 'Ресурс не знайдено'
});Повний набір маршрутів має такий вигляд:
GET /tasks
GET /tasks/:id
POST /tasks
PUT /tasks/:id
DELETE /tasks/:idПриклад послідовності запитів:
Отримати початковий список:
curl http://localhost:3000/tasksСтворити завдання:
curl -X POST http://localhost:3000/tasks \
-H "Content-Type: application/json" \
-d "{\"title\":\"Перевірити API\"}"Отримати створене завдання:
curl http://localhost:3000/tasks/3Оновити його:
curl -X PUT http://localhost:3000/tasks/3 \
-H "Content-Type: application/json" \
-d "{\"title\":\"Перевірити CRUD API\",\"completed\":true}"Видалити його:
curl -X DELETE http://localhost:3000/tasks/3express.json()Якщо не додати:
app.use(express.json());то req.body не міститиме розібраний JSON-запит.
Параметри маршруту завжди мають тип string:
req.params.idТому порівнюйте їх із числовим ідентифікатором лише після перетворення:
const id = Number.parseInt(req.params.id, 10);Не слід одразу працювати з результатом find():
const task = tasks.find((item) => item.id === id);
task.title = 'Нове значення';Якщо завдання не знайдено, task дорівнюватиме undefined, і код завершиться помилкою. Спочатку перевірте наявність ресурсу та поверніть 404.
Для успішного POST краще повертати 201 Created, а не загальний 200 OK. Це чітко повідомляє клієнту, що новий ресурс було створено.
У цьому прикладі завдання зберігаються в масиві:
let tasks = [];Такий масив існує лише під час роботи процесу Node.js. Для реального застосунку дані потрібно зберігати в базі даних, але це не є необхідним для розуміння CRUD-маршрутів.
CRUD складається з операцій створення, читання, оновлення та видалення.
У REST API цим операціям відповідають POST, GET, PUT і DELETE.
req.params використовується для читання параметрів маршруту.
req.body містить дані з тіла запиту.
Для JSON-запитів потрібен middleware express.json().
Сервер має перевіряти вхідні дані та існування ресурсу.
Правильні HTTP-статуси допомагають клієнту зрозуміти результат запиту.
Наведений API підтримує повний набір CRUD-операцій над ресурсом tasks.