Зберігання даних у глобальній змінній
Статичні сторінки для користувачів - як ви дізналися в попередньому розділі - можуть добре підходити для landing-сторінок, або для персональних блогів. Проте, якщо ви хочете видавати персоналізований контент, вам потрібно мати місце для зберігання даних.
Давайте візьмемо простий приклад: реєстрацію користувача. Ви можете надавати контент для окремих користувачів або зробити його доступним тільки після реєстрації.
Якщо користувач хоче зареєструватися на вашому додатку, вам захочеться створити обробник маршруту, щоб зробити це можливим:
const users = []
app.post('/users', function (req, res) {
// отримуємо дані користувача з body
const user = req.body
users.push({
name: user.name,
age: user.age
})
res.send('successfully registered')
})
Таким чином, ви можете зберігати користувачів в глобальній змінній, яка буде знаходитися в пам'яті протягом всього терміну служби вашого додатку.
Використання цього методу може бути проблематичним:
-
Оперативна пам'ять коштує дорого,
-
пам'ять скидається кожен раз при перезавантаженні додатка,
-
іноді все закінчується переповненням стека.
Зберігання даних в файлі
Наступний варіант - зберігати дані в файлах.
Якщо ми постійно зберігаємо дані призначені для користувача в файловій системі, ми можемо уникнути раніше перелічених проблем.
Цей метод виглядає наступним чином на практиці:
const fs = require('fs')
app.post('/users', function (req, res) {
const user = req.body
fs.appendToFile('users.txt', JSON.stringify({ name: user.name, age: user.age }), (err) => {
res.send('successfully registered')
})
})
Ми не втратимо дані користувача, навіть після перезавантаження сервера. Це рішення є також економічно ефективним, так як купувати пам'ять для зберігання дешевше, ніж купувати RAM.
Але такий вид зберігання даних користувача має декілька недоліків:
-
Додавати дані не складно, але подумайте про оновлення або видалення.
-
Якщо ми працюємо з файлами, немає легкого способу паралельно отримати доступ до них.
-
Коли ми намагаємося масштабувати наш додаток, ми не можемо розділити файли (ми можемо, але це далеко за межами рівня даного туторіалу) між серверами.
І тут на допомогу приходить справжня база даних.
Ви може вже чули про два головні типи баз даних: SQL і NoSQL.
SQL
Давайте почнемо з SQL. Це мова запитів, розроблена для роботи з базами даних. SQL має кілька особливостей в залежності від продукту, який ви використовуєте, але основи завжди однакові.
Самі дані будуть зберігатися в таблицях, і кожна вставлена частина буде представлена у вигляді рядка в таблиці, так само, як в Google Sheets або Microsoft Excel.
У базі даних SQL можна визначити схеми - ці схеми забезпечать каркас для даних, які будуть там розміщені. Типи різних значень повинні бути оголошені, перш ніж ви зможете зберігати ваші дані. Наприклад, вам потрібно буде оголосити таблицю для ваших даних користувача, і сказати базі даних, що вона має ім'я користувача - string, і вік - integer.
NoSQL
З іншого боку, бази даних NoSQL стали достатньо популярними в останнє десятиліття. З NoSQL ви не повинні оголошувати схему і можете зберігати будь-який JSON. Це зручно з JavaScript, тому що ми можемо перетворити будь-який об'єкт у JSON досить легко. Будьте обережні, тому що ви ніколи не можете гарантувати, що дані сумісні, і ви ніколи не можете знати, що є в базі даних.
Node.js та MongoDB
Існує непорозуміння з Node.js, про яке ми чуємо дуже часто:
"Node.js може використовуватись лише з MongoDB (яка є найпопулярнішою базою даних NoSQL)."
З мого досвіду, це не так. Існують драйвера для більшості бази даних, і є також відповідні бібліотеки на NPM. На мою думку, вони так само легко використовуються, як і MongoDB.
Node.js та PostgreSQL
Для простоти, ми будемо використовувати SQL в наступному прикладі, а саме PostgreSQL.
Щоб працювати з PostgreSQL, ви повинні встановити його на своєму комп'ютері. Якщо ви на Mac, ви можете використовувати homebrew. В іншому випадку, якщо ви на Linux, ви можете встановити його за допомогою вашого менеджера пакетів.
Для більш детальної інформації прочитайте цей чудовий гайд по запуску вашої першої бази даних.
Якщо ви плануєте використовувати DB браузер, я рекомендую програму psql
- вона поширюється в комплекті з установкою PostgreSQL. Ось невелика шпаргалка, яка буде в нагоді, якщо ви почнете її використовувати.
Якщо вам не подобається інтерфейс командного рядка, ви можете використовувати pgAdmin, який є open source GUI-інструментом для адміністрування PostgreSQL.
Зверніть увагу, що SQL є окремою мовою, ми не будемо розглядати всі її функції, а лише найпростіші з них. Щоб дізнатися більше, є багато хороших курсів онлайн, які охоплюють всі основи на PostgreSQL.
Робота з базою даних Node.js
По-перше, ми повинні створити базу даних, яку ми будемо використовувати. Для цього введіть наступну команду в терміналі: createdb node_hero
Після цього нам потрібно створити таблицю для наших користувачів.
CREATE TABLE users(
name VARCHAR(20),
age SMALLINT
);
І нарешті ми можемо повернутись до кодингу. Ось як ви можете працювати з вашою базою даних через програму Node.js.
'use strict'
const pg = require('pg')
const conString = 'postgres://username:password@localhost/node_hero'
pg.connect(conString, function (err, client, done) {
if (err) {
return console.error('error fetching client from pool', err)
}
client.query('SELECT $1::varchar AS my_first_query', ['node hero'], function (err, result) {
done()
if (err) {
return console.error('error happened during query', err)
}
console.log(result.rows[0])
process.exit(0)
})
})
Це був всього лише простий приклад, "hello world" в PostgreSQL. Зверніть увагу на те, що перший параметр є рядком, який є нашою SQL-командою, другий параметр - масивом значень, які ми б хотіли зберігати.
Величезною помилкою безпеки буває вставка вводу користувача в базу даних у первісному вигляді. Частими бувають т.з. SQL атаки, які є видом атак, коли атакувач намагається використати шкідливі SQL-запити. Завжди приймайте це до уваги при створенні будь-якого додатка з користувачами.
Давайте продовжимо наш попередній приклад.
app.post('/users', function (req, res, next) {
const user = req.body
pg.connect(conString, function (err, client, done) {
if (err) {
// передаємо помилку до обробника помилок express
return next(err)
}
client.query('INSERT INTO users (name, age) VALUES ($1, $2);', [user.name, user.age], function (err, result) {
done()
if (err) {
// передаємо помилку до обробника помилок express
return next(err)
}
res.send(200)
})
})
})
Тепер користувача розміщено у базі даних! Давайте спробуємо пошукати його. Додамо наступний функціонал.
app.get('/users', function (req, res, next) {
pg.connect(conString, function (err, client, done) {
if (err) {
// передаємо помилку до обробника помилок express
return next(err)
}
client.query('SELECT name, age FROM users;', [], function (err, result) {
done()
if (err) {
// передаємо помилку до обробника помилок express
return next(err)
}
res.json(result.rows)
})
})
})
Далі: Частина 6 - Модуль запитів у Node.js
Ще немає коментарів