- Зачем связывать Node.js и MongoDB
- Что получится в конце
- Что нужно заранее
- Создаем проект
- Настройки в .env
- Подключение к базе
- Первый server.js
- Добавляем документ в коллекцию
- Читаем список документов
- Полный server.js
- Важные привычки с MongoDB
- Не хранить секреты в коде
- Не принимать любой объект без проверки
- Ограничивать выдачу
- Думать об индексах
- Не путать _id и id
- Частые ошибки
- MongoServerSelectionError
- Неверный пароль в Atlas
- MONGODB_URI undefined
- Даты выглядят странно
- Ответы на эти вопросы могут быть для вас полезными
- MongoDB лучше MySQL для Node.js?
- Нужно ли использовать Mongoose?
- Можно ли использовать MongoDB локально?
- Почему коллекция появилась сама?
- Как удалить тестовые документы?
- Что почитать дальше по Node.js
Зачем связывать Node.js и MongoDB
MongoDB хорошо ложится на JavaScript-мышление: данные хранятся документами, похожими на обычные объекты. Поэтому связка Node.js + MongoDB часто встречается в учебных проектах, прототипах, админках, ботах, небольших API и MVP
Но есть тонкость. Новичок часто думает: "Раз MongoDB хранит JSON-подобные документы, значит можно просто кидать туда любые объекты". Технически можно, но лучше сразу привыкать к аккуратной структуре, проверке входных данных и хранению секретов вне кода
В этом уроке сделаем коллекцию leads и Express API для добавления и чтения заявок
Что получится в конце
Проект:
node-mongodb-api/
package.json
server.js
db.js
.env
Маршруты:
GET /api/status— проверка подключения;GET /api/leads— список заявок;POST /api/leads— добавление заявки.
Что нужно заранее
Нужны:
- Node.js LTS;
- npm;
- MongoDB локально или MongoDB Atlas;
- базовое понимание Express;
- инструмент для проверки HTTP-запросов.
Для локального MongoDB connection string часто выглядит так:
mongodb://127.0.0.1:27017
Для Atlas строка будет длиннее и с логином/паролем
Создаем проект
mkdir node-mongodb-api
cd node-mongodb-api
npm init -y
npm install express mongodb dotenv
Пакеты:
express— сервер;mongodb— официальный Node.js driver;dotenv— переменные окружения.
Настройки в .env
Создайте .env:
MONGODB_URI=mongodb://127.0.0.1:27017
MONGODB_DB=solo_lessons
PORT=3000
Если используете Atlas, не публикуйте connection string с паролем. Для статьи можно показать шаблон, но не реальный секрет
Подключение к базе
Создайте db.js:
const { MongoClient } = require('mongodb');
const client = new MongoClient(process.env.MONGODB_URI);
let database;
async function connectToDatabase() {
if (database) {
return database;
}
await client.connect();
database = client.db(process.env.MONGODB_DB);
return database;
}
module.exports = {
connectToDatabase
};
Мы не создаем новое подключение на каждый запрос. Один раз подключаемся и переиспользуем базу
Первый server.js
require('dotenv').config();
const express = require('express');
const { connectToDatabase } = require('./db');
const app = express();
const port = Number(process.env.PORT || 3000);
app.use(express.json());
app.get('/api/status', async (req, res, next) => {
try {
const db = await connectToDatabase();
await db.command({ ping: 1 });
res.json({
ok: true,
database: process.env.MONGODB_DB
});
} catch (error) {
next(error);
}
});
app.listen(port, () => {
console.log(`API запущен: http://localhost:${port}`);
});
Запуск:
node server.js
Проверка:
curl http://localhost:3000/api/status
Если ответ ok: true, подключение работает
Добавляем документ в коллекцию
Добавим POST /api/leads:
app.post('/api/leads', async (req, res, next) => {
try {
const { name, email, source } = req.body;
if (!name || !email) {
return res.status(400).json({
ok: false,
message: 'Нужны name и email'
});
}
const db = await connectToDatabase();
const collection = db.collection('leads');
const lead = {
name,
email,
source: source || 'site',
status: 'new',
createdAt: new Date()
};
const result = await collection.insertOne(lead);
res.status(201).json({
ok: true,
lead: {
id: result.insertedId,
...lead
}
});
} catch (error) {
next(error);
}
});
Проверка:
curl -X POST http://localhost:3000/api/leads \
-H "Content-Type: application/json" \
-d '{"name":"Анна","email":"anna@example.com","source":"landing"}'
MongoDB сама создаст базу и коллекцию при первой записи, если их еще не было
Читаем список документов
app.get('/api/leads', async (req, res, next) => {
try {
const db = await connectToDatabase();
const collection = db.collection('leads');
const leads = await collection
.find({})
.sort({ createdAt: -1 })
.limit(50)
.toArray();
res.json({
ok: true,
leads
});
} catch (error) {
next(error);
}
});
Проверка:
curl http://localhost:3000/api/leads
Если заявка появилась в массиве, API работает
Полный server.js
require('dotenv').config();
const express = require('express');
const { connectToDatabase } = require('./db');
const app = express();
const port = Number(process.env.PORT || 3000);
app.use(express.json());
app.get('/api/status', async (req, res, next) => {
try {
const db = await connectToDatabase();
await db.command({ ping: 1 });
res.json({
ok: true,
database: process.env.MONGODB_DB
});
} catch (error) {
next(error);
}
});
app.get('/api/leads', async (req, res, next) => {
try {
const db = await connectToDatabase();
const collection = db.collection('leads');
const leads = await collection
.find({})
.sort({ createdAt: -1 })
.limit(50)
.toArray();
res.json({
ok: true,
leads
});
} catch (error) {
next(error);
}
});
app.post('/api/leads', async (req, res, next) => {
try {
const { name, email, source } = req.body;
if (!name || !email) {
return res.status(400).json({
ok: false,
message: 'Нужны name и email'
});
}
const db = await connectToDatabase();
const collection = db.collection('leads');
const lead = {
name,
email,
source: source || 'site',
status: 'new',
createdAt: new Date()
};
const result = await collection.insertOne(lead);
res.status(201).json({
ok: true,
lead: {
id: result.insertedId,
...lead
}
});
} catch (error) {
next(error);
}
});
app.use((error, req, res, next) => {
console.error(error);
res.status(500).json({
ok: false,
message: 'Внутренняя ошибка сервера'
});
});
app.listen(port, () => {
console.log(`API запущен: http://localhost:${port}`);
});
Важные привычки с MongoDB
Не хранить секреты в коде
Connection string с паролем должен жить в .env или настройках хостинга
Не принимать любой объект без проверки
MongoDB гибкая, но API должен быть строгим. Если заявке нужны name и email, проверяйте их
Ограничивать выдачу
В примере стоит .limit(50). Без лимита можно случайно вернуть слишком много документов
Думать об индексах
Когда коллекция растет, запросы по email, статусу или дате лучше поддерживать индексами
Не путать _id и id
MongoDB создает _id. В ответе API можно вернуть его как id, но внутри базы это ObjectId
Частые ошибки
MongoServerSelectionError
Приложение не может подключиться к MongoDB. Проверьте, запущен ли сервер, верный ли MONGODB_URI, открыта ли сеть для Atlas
Неверный пароль в Atlas
Проверьте пользователя базы, пароль, IP allowlist и правильность connection string
MONGODB_URI undefined
Не подключен dotenv или файл .env лежит не в корне проекта. В server.js должна быть строка:
require('dotenv').config();
Даты выглядят странно
new Date() хранит дату в формате, удобном для машины. Для вывода пользователю форматируйте дату отдельно
Ответы на эти вопросы могут быть для вас полезными
MongoDB лучше MySQL для Node.js?
Не лучше и не хуже, а другая. MongoDB удобна для документов и гибкой структуры. MySQL удобен для таблиц, связей и строгой схемы
Нужно ли использовать Mongoose?
Не обязательно. Для первого понимания полезно начать с официального драйвера MongoDB. Mongoose можно изучить позже, когда понадобится схема и модели
Можно ли использовать MongoDB локально?
Да. Для учебы локальная MongoDB подходит. Для облачного старта часто используют MongoDB Atlas
Почему коллекция появилась сама?
MongoDB может создать базу и коллекцию при первой записи. Это удобно, но не отменяет проектирование структуры данных
Как удалить тестовые документы?
Можно использовать MongoDB Compass, shell или отдельный route в учебном проекте. В реальном API удаление лучше делать с авторизацией
Что почитать дальше по Node.js
Если вы собираете тему по шагам, рядом лучше открыть:
- Первый сервер на Express — вернуться к базовому Express API.
- Node.js + MySQL: REST API для первых данных — сравнить MongoDB с MySQL на похожем REST-сценарии.
- Хостинг для Node.js сайта: что проверять перед выбором — понять, как учесть базу данных при деплое.
- Как обновить Node.js без боли — не ломать драйверы и зависимости при обновлении Node.js.



