У сучасному цифровому світі API (інтерфейси програмування додатків) є основою для веб-застосунків. Незалежно від того, чи створюєте ви односторінковий додаток, мобільний додаток чи інтегруєтесь з іншими сервісами, наявність надійного API є критично важливою. У цьому туторіалі ми розглянемо створення власного RESTful API за допомогою Node.js, Express та MongoDB — потужного набору інструментів для побудови масштабованих серверних рішень.
Як студент третього курсу з веб-розробки, я усвідомив, що створення власних API значно покращує розуміння серверної архітектури. Ця стаття поділиться моїм досвідом і надасть покрокову інструкцію для студентів, які хочуть створити свої власні API.
Перед початком
Перед тим, як почати, переконайтесь, що у вас є:
- Базові знання JavaScript.
- Встановлений Node.js на вашому комп'ютері.
- Редактор коду (наприклад, VS Code або Sublime Text).
- Встановлений MongoDB локально або доступ до MongoDB Atlas.
- Інструмент для тестування API, такий як Postman.
Налаштування проєкту
Спершу створимо новий проєкт і встановимо необхідні залежності:
Створюємо директорію для проєкту
mkdir custom-api
cd custom-api
Ініціалізуємо Node.js проект
npm init -y
Встановлюємо необхідні пакети
npm install express mongoose dotenv cors
npm install --save-dev nodemon
Ці пакети виконують такі функції:
- express — веб-фреймворк для Node.js.
- mongoose — інструмент для моделювання даних MongoDB.
- dotenv — завантажує змінні середовища з файлу .env
.
- cors — дозволяє робити запити між різними доменами.
- nodemon — автоматично перезапускає сервер під час розробки.
Структура проєкту
Щоб підтримувати організовану структуру, ми створимо такі каталоги:
custom-api/
├── node_modules/
├── config/
│ └── db.js
├── controllers/
│ └── productController.js
├── models/
│ └── Product.js
├── routes/
│ └── productRoutes.js
├── .env
├── .gitignore
├── package.json
└── server.js
Створюємо відповідні директорії:
mkdir config controllers models routes
Підключення до MongoDB
Для підключення до MongoDB створимо файл .env
в кореневій директорії:
PORT=5000
MONGO_URI=mongodb://localhost:27017/apidb
Далі налаштуємо підключення до бази даних у файлі config/db.js
:
const mongoose = require('mongoose');
const connectDB = async () => {
try {
const conn = await mongoose.connect(process.env.MONGO_URI, {
useNewUrlParser: true,
useUnifiedTopology: true
});
console.log(MongoDB підключено: ${conn.connection.host}
);
} catch (error) {
console.error(Помилка: ${error.message}
);
process.exit(1);
}
};
module.exports = connectDB;
Створення моделі даних
Тепер створимо просту модель для продуктів у файлі models/Product.js
:
const mongoose = require('mongoose');
const productSchema = mongoose.Schema({
name: {
type: String,
required: [true, 'Будь ласка, додайте назву продукту'],
trim: true
},
description: {
type: String,
required: [true, 'Будь ласка, додайте опис']
},
price: {
type: Number,
required: [true, 'Будь ласка, додайте ціну'],
min: 0
},
category: {
type: String,
required: [true, 'Будь ласка, додайте категорію']
},
inStock: {
type: Boolean,
default: true
}
}, {
timestamps: true
});
module.exports = mongoose.model('Product', productSchema);
Створення контролерів
Контролери містять логіку для обробки запитів. Давайте створимо контролер продуктів у файлі controllers/productController.js
:
const Product = require('../models/Product');
// Отримати всі продукти
const getProducts = async (req, res) => {
try {
const products = await Product.find();
res.status(200).json(products);
} catch (error) {
res.status(500).json({ message: error.message });
}
};
// Отримати один продукт
const getProductById = async (req, res) => {
try {
const product = await Product.findById(req.params.id);
if (!product) {
return res.status(404).json({ message: 'Продукт не знайдений' });
}
res.status(200).json(product);
} catch (error) {
res.status(500).json({ message: error.message });
}
};
// Створити новий продукт
const createProduct = async (req, res) => {
try {
const product = await Product.create(req.body);
res.status(201).json(product);
} catch (error) {
res.status(400).json({ message: error.message });
}
};
// Оновити продукт
const updateProduct = async (req, res) => {
try {
const product = await Product.findById(req.params.id);
if (!product) {
return res.status(404).json({ message: 'Продукт не знайдений' });
}
const updatedProduct = await Product.findByIdAndUpdate(
req.params.id,
req.body,
{ new: true, runValidators: true }
);
res.status(200).json(updatedProduct);
} catch (error) {
res.status(400).json({ message: error.message });
}
};
// Видалити продукт
const deleteProduct = async (req, res) => {
try {
const product = await Product.findById(req.params.id);
if (!product) {
return res.status(404).json({ message: 'Продукт не знайдений' });
}
await product.deleteOne();
res.status(200).json({ message: 'Продукт видалено' });
} catch (error) {
res.status(500).json({ message: error.message });
}
};
module.exports = {
getProducts,
getProductById,
createProduct,
updateProduct,
deleteProduct
};
Налаштування маршрутів
Тепер налаштуємо маршрути в файлі routes/productRoutes.js
:
const express = require('express');
const router = express.Router();
const {
getProducts,
getProductById,
createProduct,
updateProduct,
deleteProduct
} = require('../controllers/productController');
// GET /api/products
router.get('/', getProducts);
// GET /api/products/:id
router.get('/:id', getProductById);
// POST /api/products
router.post('/', createProduct);
// PUT /api/products/:id
router.put('/:id', updateProduct);
// DELETE /api/products/:id
router.delete('/:id', deleteProduct);
module.exports = router;
Створення сервера
Давайте налаштуємо сервер у файлі server.js
:
const express = require('express');
const dotenv = require('dotenv');
const cors = require('cors');
const connectDB = require('./config/db');
// Завантажуємо змінні середовища
dotenv.config();
// Підключаємося до бази даних
connectDB();
// Ініціалізуємо express
const app = express();
// Middleware
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
// Маршрути
app.use('/api/products', require('./routes/productRoutes'));
// Корінний маршрут
app.get('/', (req, res) => {
res.send('API працює...');
});
// Запускаємо сервер
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => console.log(Сервер працює на порту ${PORT}
));
Тестування API
Оновіть секцію скриптів у package.json
:
"scripts": {
"start": "node server.js",
"dev": "nodemon server.js"
}
Тепер запустимо сервер:
npm run dev
Ви побачите повідомлення:
Сервер працює на порту 5000
MongoDB підключено: localhost
Тепер протестуємо API-ендпоінти за допомогою Postman:
- Створити продукт (POST):
- URL:
http://localhost:5000/api/products
- Тіло (raw JSON):
{ "name": "Бездротові навушники", "description": "Безшумні бездротові навушники з акумулятором на 20 годин", "price": 149.99, "category": "Електроніка", "inStock": true }
2. Отримання всіх продуктів (GET):
- URL:
http://localhost:5000/api/products
3. Отримання конкретного продукту (GET):
- URL:
http://localhost:5000/api/products/[product_id]
4. Оновлення продукту (PUT):
- URL:
http://localhost:5000/api/products/[product_id]
- Тіло (raw JSON):
{ "price": 129.99, "inStock": false }
5. Видалення продукту (DELETE):
- URL:
http://localhost:5000/api/products/[product_id]
Додавання валідації вводу
Щоб підвищити надійність нашого API, давайте додамо валідацію вхідних даних. Для цього встановимо express-validator:
npm install express-validator
Тепер оновимо наші маршрути:
const express = require('express');
const router = express.Router();
const { body, validationResult } = require('express-validator');
const {
getProducts,
getProductById,
createProduct,
updateProduct,
deleteProduct
} = require('../controllers/productController');
// Middleware для валідації
const validateProduct = [
body('name').notEmpty().withMessage('Name is required'),
body('description').notEmpty().withMessage('Description is required'),
body('price').isNumeric().withMessage('Price must be a number').isFloat({ min: 0 }).withMessage('Price must be positive'),
body('category').notEmpty().withMessage('Category is required'),
(req, res, next) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
next();
}
];
// Маршрути
router.get('/', getProducts);
router.get('/:id', getProductById);
router.post('/', validateProduct, createProduct);
router.put('/:id', updateProduct);
router.delete('/:id', deleteProduct);
module.exports = router;
Висновок
Вітаємо! Ви успішно створили RESTful API за допомогою Node.js, Express і MongoDB. Цей API відповідає кращим практикам, включаючи правильну структуру проєкту, налаштування середовища, підключення до бази даних, проектування RESTful маршрутів, розділення логіки контролерів і валідацію вводу.
Цей фундамент можна розширити для створення більш складних API з такими функціями, як аутентифікація за допомогою JWT, обмеження швидкості, розширене фільтрування і пагінація, завантаження файлів та логування помилок.
Як веб-розробники, створення власних API дає нам повний контроль над даними і відкриває можливості для створення складних застосунків. Сподіваюсь, цей урок допоможе вам на вашому шляху в веб-розробці!
Наступні кроки
Щоб вдосконалити цей API, розгляньте:
- Додавання аутентифікації користувачів
- Реалізацію функціональності розширеного пошуку
- Налаштування автоматизованого тестування
- Документування API за допомогою Swagger
- Розгортання на хмарній платформі, як Heroku або AWS
Щасливого кодування!
Перекладено з: How to Build a Custom API with Node.js, Express, and MongoDB