Привет, Хабр!
Сегодня мы продемонстрируем как создавать back-end приложения на Node.js c PostqreSQL. В качестве примера создадим простейший back-end на Node.js с использованием PostgreSQL.
Почему именно Node.js и PostgreSQL? Node.js имеет хорошую скорость и асинхронность, а PostgreSQL, в свою очередь, является мощной и надежной СУБД.
Вместе они создают идеальный тандем для создания качественных приложений.
Создание и настройка проекта
Все будем делать на Винде.
Установим
Node.Js
Переходим на официальный сайт Node.js и скачиваем установочный файл для Windows.
Далее запускаем установочный файл и следуйте инструкциям мастера установки.
Здесь еще важно, чтобы был выбран флажок для установки npm вместе с Node.js.
После завершения установки открываем командную строку и вводим node -v и npm -v, чтобы проверить успешность установки.
PostgreSQL
Скачиваем PostgreSQL с официального сайта. Установка там достаточна простая, но важно проверить, что включены pgAdmin и psql.
Далее создаем саму базы данных и юзера.
Открываем командную строку или терминал.
Входим в консоль PostgreSQL от имени суперпользователя (обычно postgres):
sudo -i -u postgres psql
Создаем новую БД:
CREATE DATABASE mydatabase;
Создайте нового пользователя с паролем:
CREATE USER myuser WITH ENCRYPTED PASSWORD 'qwerty';
Даем пользователю права на созданную БД:
GRANT ALL PRIVILEGES ON DATABASE mydatabase TO myuser;
Выходим из консоли PostgreSQL командой \q.
Инициализация нового проекта Node.js
Создадим новую директорию для проекта:
mkdir my-node-project cd my-node-project
Инициализируем проект с помощью npm:
npm init -y
Это создаст файл package.json, который будет содержать основную инфу о проекте, включая зависимости и скрипты для запуска проекта.
Установим необходимые пакеты для работы с Express и PostgreSQL:
npm install express pg dotenv
Express: фреймворк для создания серверных приложений на Node.js.
pg: оф. клиент для PostgreSQL.
dotenv: для управления переменными окружения.
Организуем проект таким образом, чтобы было легко управлять и расширять его:
my-node-project/ │ ├── src/ │ ├── routes/ │ │ └── index.js │ ├── controllers/ │ │ └── userController.js │ ├── models/ │ │ └── userModel.js │ ├── config/ │ │ └── db.js │ └── app.js ├── .env ├── package.json └── README.md
routes: маршруты приложения.
controllers: логика обработки запросов.
models: модели базы данных.
config: конфиг, который включает настройки подключения к БД.
app.js: главный файл приложения.
Подключение к базе данных
Создадим файл конфигурации для подключения к БД, например, db.js:
const { Pool } = require('pg'); require('dotenv').config(); const pool = new Pool({ user: process.env.DB_USER, host: process.env.DB_HOST, database: process.env.DB_NAME, password: process.env.DB_PASSWORD, port: process.env.DB_PORT, }); module.exports = pool;
Добавляем переменные окружения в файл .env:
DB_USER=yourusername DB_HOST=localhost DB_NAME=yourdatabase DB_PASSWORD=yourpassword DB_PORT=5432
Создаем тестовый запрос в app.js, чтобы убедиться, что соединение с базой данных установлено:
const express = require('express'); const pool = require('./config/db'); const app = express(); pool.query('SELECT NOW()', (err, res) => { if(err) { console.error('Error connecting to the database', err.stack); } else { console.log('Connected to the database:', res.rows); } }); const PORT = process.env.PORT || 3000; app.listen(PORT, () => { console.log(`Server running on port ${PORT}`); });
Создание API с использованием Express
Создадим файл маршрутов index.js и определим базовые маршруты:
const express = require('express'); const router = express.Router(); const userController = require('../controllers/userController'); router.get('/users', userController.getUsers); router.post('/users', userController.createUser); router.put('/users/:id', userController.updateUser); router.delete('/users/:id', userController.deleteUser); module.exports = router;
В контроллере userController.js описываем логику взаимодействия с базой данных:
const pool = require('../config/db'); exports.getUsers = async (req, res) => { try { const result = await pool.query('SELECT * FROM users'); res.status(200).json(result.rows); } catch (err) { res.status(500).json({ error: err.message }); } }; exports.createUser = async (req, res) => { const { name, email } = req.body; try { const result = await pool.query('INSERT INTO users (name, email) VALUES ($1, $2) RETURNING *', [name, email]); res.status(201).json(result.rows[0]); } catch (err) { res.status(500).json({ error: err.message }); } }; exports.updateUser = async (req, res) => { const { id } = req.params; const { name, email } = req.body; try { const result = await pool.query('UPDATE users SET name = $1, email = $2 WHERE id = $3 RETURNING *', [name, email, id]); res.status(200).json(result.rows[0]); } catch (err) { res.status(500).json({ error: err.message }); } }; exports.deleteUser = async (req, res) => { const { id } = req.params; try { await pool.query('DELETE FROM users WHERE id = $1', [id]); res.status(204).send(); } catch (err) { res.status(500).json({ error: err.message }); } };
Юзаем middleware для валидации данных и обработки ошибок:
const express = require('express'); const app = express(); const routes = require('./routes'); const { body, validationResult } = require('express-validator'); app.use(express.json()); app.post('/users', body('email').isEmail(), body('name').notEmpty(), (req, res, next) => { const errors = validationResult(req); if (!errors.isEmpty()) { return res.status(400).json({ errors: errors.array() }); } next(); }, routes ); app.use('/api', routes); app.use((err, req, res, next) => { console.error(err.stack); res.status(500).send('Something broke!'); }); const PORT = process.env.PORT || 3000; app.listen(PORT, () => { console.log(`Server running on port ${PORT}`); });
Тестирование и отладка
Теперь, когда API создан и подключен к базе данных, можно и нужно начинать откладывать и тестировать.
Postman хорошо справится с этой задачей.
Создаем запрос в Postman:
Запускаем Postman и создаем новый запрос.
Вводим URL API, например,
http://localhost:3000/api/users.Выбираем метод запроса: GET, POST, PUT, DELETE.
Если запрос требует тела, например, POST или PUT, добавляемJSON-данные в разделе Body.
Отправка запроса и проверка ответа:
Нажимаем «Send» и проверяемответ в нижней части окна Postman
Можно реализовать логирование
Установим библиотеку winston для логирования:
npm install winston
Создадим файл logger.js для настройки логирования:
const { createLogger, format, transports } = require('winston'); const logger = createLogger({ level: 'info', format: format.combine( format.timestamp(), format.json() ), transports: [ new transports.Console(), new transports.File({ filename: 'error.log', level: 'error' }), new transports.File({ filename: 'combined.log' }) ], }); module.exports = logger;
Импортируем и используем логер в app.js и других файлах:
const logger = require('./logger'); app.use((req, res, next) => { logger.info(`${req.method} ${req.url}`); next(); }); app.use((err, req, res, next) => { logger.error(err.message); res.status(500).send('Something broke!'); });
Теперь мы уже создали готовый и простейший back-end на Node.js с использованием PostgreSQL, а также подключили логирование и Postman. Кстати, сюда еще можно добавить модульное тестирование с помощью библиотеки Jest.
Cоздавать back-end на Node.js с использованием PostgreSQL позволяет воспользоваться всеми фичами этих технологий!
Всех желающих приглашаем на открытый урок по пользовательским типам данных в PostgreSQL, который пройдет 23 июля.
На этом открытом уроке расскажем о возможностях PostgreSQL в части создания собственных типов данных. Разберем, как можно создать пользовательский тип, как с ним работать и несколько примеров детально «до винтика».
Записаться на урок можно бесплатно по ссылке.
