Драйвер MongoDB
Драйвер MongoDB
Драйвер MongoDB Node.js дозволяє взаємодіяти з базами даних MongoDB з програм Node.js. Драйвер знадобиться нам для підключення до бази даних та виконання запитів. Якщо у вас не встановлено драйвер MongoDB Node.js, ви можете встановити його в проект за допомогою наступної команди.
npm install mongodb
Модуль MongoDB експортує MongoClient
, він використовується для підключення до
бази даних MongoDB, виконання операцій та закриття з'єднання з цим кластером.
Також ми експортуємо ObjectId
він знадобиться нам, щоб перетворити рядок
до об'єкту _id
MongoDB
const { MongoClient, ObjectId } = require('mongodb');
Перше, що нам потрібно зробити це помістити константу URI підключення у
змінну оточення DB_HOST
. URI підключення - це рядок підключення,
Ви скопіювали з Atlas у попередньому розділі. Помістимо її у файл .env
DB_HOST=mongodb+srv://<username>:<password>@<your-cluster-url>/test?retryWrites=true&w=majority
У самій програмі отримаємо доступ до URI
require('dotenv').config();
const uriDb = process.env.DB_HOST;
Тепер, коли ми маємо URI, ми можемо створити екземпляр MongoClient
.
const client = await new MongoClient(uriDb, {
useUnifiedTopology: true,
}).connect();
Використати екземпляр MongoClient
для підключення до нашого кластера можна
після виконання connect()
. Функція поверне нам обіцянку, і ми ставимо await
,
щоб дочекатися екземпляр підключення. Після цього ми готові взаємодіяти з
нашою базою даних.
Виклики функцій, що взаємодіють із базою даних, ми помістимо в оператори
try/catch
, щоб обробляти будь-які несподівані помилки.
try {
// робота з базою даних
} catch (e) {
console.error(e);
}
Насамкінець ми закриваємо підключення до нашої бази, тому закінчуємо try/catch
оператором finally
.
finally {
await client.close();
}
REST API
Перепишемо на програму з розділу REST API з використанням бази даних MongoDB. Повний код програми:
Модифікації зазнав файл роутингу api/index.js
. Розглянемо докладніше
зміни та почнемо з обробника роутингу /tasks
router.get('/tasks', async (req, res, next) => {
const client = await new MongoClient(uriDb, {
useUnifiedTopology: true,
}).connect();
try {
const results = await client.db().collection('todos').find().toArray();
res.json({
status: 'success',
code: 200,
data: {
tasks: results,
},
});
} catch (e) {
console.error(e);
next(e);
} finally {
await client.close();
}
});
Ми створюємо екземпляр підключення у базі даних MongoDB. Всю логіку
взаємодії ми поміщаємо в оператор try/catch
. Знаходимо всі можливі завдання
const results = await client.db().collection('todos').find().toArray();
Тут необхідно звернути увагу, що оператор find
повертає нам курсор, та
необхідно перетворити його на масив методом toArray
. Після ми відправляємо,
як і раніше результат у вигляді JSON.
У принципі робота інших обробників загалом схожа і вони мають загальну схему з деякими відмінностями.
При отриманні завдання по id
, ми перетворюємо рядок id
на об'єкт ObjectId
const objectId = new ObjectId(id);
Після виконуємо деструктуризації єдиного об'єкта завдання
const [result] = await client
.db()
.collection('todos')
.find({ _id: objectId })
.toArray();
І у змінній result
лежатиме шуканий об'єкт приблизно такого виду
{
"_id": "5f8644b9cf20df3314f5b7b7",
"title": "My work",
"text": "The best",
"isDone": false
}
Створення нового завдання ми виконуємо наступною командою. Роут очікує об'єкт виду
{
"title": "My work",
"text": "The best"
}
А збереження у базі відбувається через функцію insertOne
const result = await client
.db()
.collection('todos')
.insertOne({ title, text, isDone: false });
Ми вставляємо новий документ у базу і результатом буде об'єкт, що містить:
{
"acknowledged": true,
"insertedId": "61264cb97361c8156dbf793c"
}
Властивість insertedId
містить ObjectId
із вставленим документом. Відправляємо
JSON з отриманим результатом.
res.status(201).json({
status: 'success',
code: 201,
data: { task: result },
});
Оновлення PUT та PATCH майже ідентичні
const { value: result } = await client
.db()
.collection('todos')
.findOneAndUpdate(
{ _id: objectId },
{ $set: { title, text } },
{ returnDocument: 'after' },
);
Результат операції об'єкт з властивістю value
, куди драйвер помістить
оновлений документ. Першим параметром для функції findOneAndUpdate
ми
вказуємо критерій пошуку { _id: objectId }
. Другий параметр – це об'єкт
оновлення { $set: { title, text } }
, де ми використовуємо модифікатор $set
,
щоб відбулося оновлення лише вказаних полів, а не повна заміна документа
на ці поля. Третій параметр { returnDocument: 'after' }
говорить про те, що ми
хочемо отримати не вихідний документ, а вже оновлений.
Видалення виконуємо за допомогою функції findOneAndDelete
:
const { value: result } = await client
.db()
.collection('todos')
.findOneAndDelete({ _id: objectId });
Тут ми поступили трохи інакше. Попереднього разу ми повертали статус
204
, у цей 200
и удаленный документ.
Слід зазначити, що це спрощений навчальний приклад. Він показує
підключення до бази MongoDB та виконання найпростіших запитів. Наприклад, всю логіку
роботи ми помістили в роути, але "правильно" було б роботу з базою винести в
окремий, сервіс, а логіку роботи обробників перенести на контролери. Також
ми не обробляємо помилки відсутності шуканих документів у базі та не повертаємо
при цьому помилку 404 (Not found)
. Ці речі були спеціально опущені, щоб
показати саме роботу з драйвером MongoDB, але надалі під час розгляду ODM
Mongoose ми побудуємо нашу програму більш "правильно".
API доступно по URL: https://nodebook-api-mongodb.glitch.me/api/tasks/.
І ви знову можете за допомогою Postman виконати усі CRUD операції