Гид по технологиям

CRUD API на Node.js и PostgreSQL

6 min read Разработка Обновлено 05 Jan 2026
CRUD API на Node.js и PostgreSQL
CRUD API на Node.js и PostgreSQL

Женщина пишет на белой доске

Краткие определения:

  • CRUD — стандартный набор операций с данными: Create (создать), Read (читать), Update (обновить), Delete (удалить).
  • Express — минималистичный фреймворк для Node.js для создания HTTP-серверов.
  • PostgreSQL — реляционная база данных с открытым исходным кодом.

Что вы получите из этого руководства

  • Полный рабочий пример проекта: настройка Express, подключение к PostgreSQL через pg, функции CRUD и маршруты.
  • Практические советы по обработке ошибок, безопасности и тестированию.
  • Контрольный список для разработчика, администратора БД и тестировщика.

Предварительные требования

  • Установлен Node.js.
  • Установлен PostgreSQL (локально или доступен по сети).
  • Базовое знакомство с Express.js и SQL.

Важно: в примерах используется порт 3000 и база данных notedb. Замените значения на свои в конфигурации.

Шаг 1 — Создаём Express-сервер

Создайте новую папку и инициализируйте npm:

mkdir notes
cd notes
npm init -y

Установите Express:

npm install express

Создайте файл index.js с минимальной конфигурацией сервера:

const express = require("express");
const app = express();

app.use(express.urlencoded({
  extended: true
}));

app.use(express.json())
app.listen(3000, () => console.log("Listening on port 3000"));

Этот код создаёт HTTP-сервер, который слушает порт 3000 и умеет читать JSON в теле запроса.

Шаг 2 — Создаём базу данных PostgreSQL

В psql выполните:

postgres=# CREATE DATABASE notedb;

Проверьте список баз:

postgres=# \l

Затем подключитесь к базе notedb:

postgres=# \c notedb

Создайте таблицу notes:

notedb=# CREATE TABLE notes (
  ID SERIAL PRIMARY KEY,
  note VARCHAR(255)
);

Эта таблица содержит автоинкрементный идентификатор и текст заметки.

Шаг 3 — Подключаем Node к PostgreSQL

Установите клиент для PostgreSQL:

npm install pg

Хорошая практика — вынести подключение в отдельный файл. Создайте db.js:

const { Client } = require("pg");
const { user, host, database, password, port } = require("./dbConfig");

const client = new Client({
  user,
  host,
  database,
  password,
  port,
});

client.connect();
module.exports = client;

Создайте файл dbConfig.js и добавьте свои данные подключения:

module.exports = {
  user: "{dbUser}",
  host: "{dbHost}",
  database: "notedb",
  password: "{dbPassword}",
  port: 5432,
};

Замените {dbUser}, {dbHost}, {dbPassword} на реальные значения. Если PostgreSQL запущен локально, host обычно “localhost”.

Совет по безопасности: не храните реальные пароли в репозитории. Используйте .env и библиотеку dotenv или переменные окружения.

Шаг 4 — Реализуем функции CRUD в helper.js

Вынесем логику работы с базой в отдельный модуль helper.js. Подключите клиент:

const client = require("./db");

Реализация функций:

Создание заметки:

const createNote = (req, res) => {
  try {
    const { note } = req.body;

    if (!note) {
      throw Error("Send note in request body");
    }

    client.query(
      "INSERT INTO notes (note) VALUES ($1)",
      [note],
      (err, data) => {
        res.status(201).json({
          error: null,
          message: "Created new note",
        });
      }
    );
  } catch (error) {
    res.status(500).json({
      error: error.message,
      message: "Failed to create new note",
    });
  }
};

Получение всех заметок:

const getNotes = (req, res) => {
  try {
    client.query("SELECT * FROM notes", (err, data) => {
      if (err) throw err;

      res.status(200).json({
        err: null,
        notes: data.rows,
      });
    });
  } catch (error) {
    res.status(500).json({
      err: error.message,
      notes: null,
    });
  }
};

Получение заметки по ID:

const getNoteById = (req, res) => {
  try {
    const { id } = req.params;
    client.query("SELECT * FROM notes WHERE id=$1", [id], (err, data) => {
      if (err) throw err;

      res.status(200).json({
        err: null,
        note: data.rows[0],
      });
    });
  } catch (error) {
    res.status(500).json({
      err: error.message,
      note: null,
    });
  }
};

Обновление заметки по ID:

const updateNoteById = (req, res) => {
  try {
    const { id } = req.params;
    const { note } = req.body;
    client.query(
      "UPDATE notes SET note = $1 WHERE id = $2",
      [note, id],
      (err, data) => {
        if (err) throw err;

        res.status(201).json({
          err: null,
          message: "Updated note",
        });
      }
    );
  } catch (error) {
    res.status(500).json({
      err: error.message,
      message: "Failed to update note",
    });
  }
};

Удаление заметки по ID:

const deleteNote = (req, res) => {
  try {
    const { id } = req.params;
    client.query("DELETE FROM notes WHERE id=$1", [id], (err, data) => {
      if (err) throw err;

      res.status(200).json({
        error: null,
        message: "Note deleted",
      });
    });
  } catch (error) {
    res.status(500).json({
      error: error.message,
      message: "Failed to delete note",
    });
  }
};

И экспортируем функции:

module.exports = { createNote, getNotes, getNoteById, updateNoteById, deleteNote };

Примечание: в коде выше используется callback-стиль client.query. Альтернатива — использовать async/await с client.query(…).then(…) или pool.query и промисы для лучшей читаемости и обработки ошибок.

Шаг 5 — Создаём маршруты API в index.js

В index.js импортируйте helper и зарегистрируйте маршруты:

const db = require("./helper")

app.get("/notes", db.getNotes);
app.get("/note/:id", db.getNoteById);
app.put("/note/:id", db.updateNoteById);
app.post("/note", db.createNote);
app.delete("/note/:id", db.deleteNote);

Теперь API готов к запросам. Примеры запросов можно отправлять через curl, Postman или встроенные тесты.

Рекомендации по структуре проекта и масштабированию

  • Разделяйте слои: маршруты, контроллеры (helper), доступ к данным (db) и конфигурация.
  • Для реального приложения используйте connection pool (pg.Pool) вместо одиночного клиента.
  • Введите миграции (например, с помощью node-pg-migrate или Flyway) для версионирования схемы БД.

Ошибки и отладка — что проверять

  • Неправильные данные в dbConfig.js: host, user, password.
  • Порт занят: если порт 3000 уже используется, поменяйте на другой.
  • Проблемы с разрешениями пользователя PostgreSQL.
  • SQL-инъекции: всегда используйте параметризованные запросы ($1, $2). В примере это сделано.

Important: клиентские ошибки (400-е) лучше обрабатывать отдельно и возвращать осмысленные сообщения. В примере общая обработка ошибок возвращает 500.

Безопасность и эксплуатация

  • Не храните секреты в репозитории. Используйте переменные окружения.
  • Ограничьте права пользователя БД: давайте минимальные права (INSERT/SELECT/UPDATE/DELETE) для этой схемы.
  • В продакшене используйте TLS для соединения с БД, если она удалённая.
  • Валидация входных данных: проверяйте длину, формат и типы полей.

Тестирование и критерии приёмки

Критерии приёмки:

  • POST /note создаёт запись с кодом 201 и сообщением “Created new note”.
  • GET /notes возвращает массив заметок и код 200.
  • GET /note/:id возвращает объект заметки с кодом 200 или 404, если не найдено.
  • PUT /note/:id обновляет заметку и возвращает код 201.
  • DELETE /note/:id удаляет заметку и возвращает код 200.

Пример тестов (на уровне поведения):

  • Проверить создание с пустым телом — ожидается 500 и понятная ошибка.
  • Проверить создание и затем получение по ID — данные должны совпадать.
  • Проверить обновление несуществующего ID — ожидается 200 (но полезно вернуть 404). Рассмотрите улучшение возврата статусов.

Разные подходы и альтернативы

  • Вместо callbacks используйте async/await:
const createNoteAsync = async (req, res) => {
  try {
    const { note } = req.body;
    if (!note) return res.status(400).json({ error: 'note required' });
    await client.query('INSERT INTO notes (note) VALUES ($1)', [note]);
    res.status(201).json({ message: 'Created new note' });
  } catch (e) {
    res.status(500).json({ error: e.message });
  }
};
  • Для более сложных приложений используйте ORM (TypeORM, Sequelize) или query builder (Knex).

Mini-методология разработки API

  1. Спроектируйте контракты (контент ответов, коды статуса).
  2. Напишите миграции и инициализацию БД.
  3. Реализуйте минимальные маршруты и контроллеры.
  4. Добавьте валидацию и обработку ошибок.
  5. Напишите интеграционные тесты.
  6. Разверните на staging и прогоните сценарии.

Чек-лист по ролям

Разработчик:

  • Разделены слои (routes/controllers/db)
  • Есть обработка ошибок
  • Есть unit/интеграционные тесты

Администратор БД:

  • Настроены права пользователя
  • Сделаны резервные копии
  • Включён мониторинг доступности БД

Тестировщик:

  • Тесты на все маршруты
  • Тесты на неправильные тела запросов
  • Тест на конкурентные запросы

Решение типичных проблем — дерево решений

flowchart TD
  A[API не отвечает] --> B{Сервер запущен?}
  B -- Нет --> C[Запустить Node.js]
  B -- Да --> D{Порт занят?}
  D -- Да --> E[Изменить порт или убить процесс]
  D -- Нет --> F{Подключение к БД установлено?}
  F -- Нет --> G[Проверить dbConfig и логи PostgreSQL]
  F -- Да --> H[Проверить маршруты и логи приложения]

Когда этот подход не подходит

  • Проект с очень сложными бизнес-правилами: предпочтительнее слои домена и ORM.
  • Требуется горизонтальное масштабирование с множеством соединений к БД — используйте пул и репликацию.

Совместимость и миграция

  • При миграции схемы применяйте миграции с версионностью.
  • Для zero-downtime обновлений избегайте удаления полей — сначала добавляйте новые, затем переключайте код.

Полезные команды и сниппеты

  • Инициализация npm: npm init -y
  • Установка модулей: npm install express pg
  • Пример curl для создания заметки:
curl -X POST http://localhost:3000/note -H "Content-Type: application/json" -d '{"note":"текст заметки"}'

Итог

Вы получили минимальную, но рабочую реализацию CRUD API на Node.js с PostgreSQL. Для продакшена доработайте обработку ошибок, валидацию, безопасность, миграции и мониторинг. Начните с компактного кода, затем итеративно улучшайте отдельные слои.

Ключевые рекомендации:

  • Используйте параметризованные запросы.
  • Не храните секреты в коде.
  • Переходите на async/await и pool для стабильности.

Краткая сводка в конце:

  • Сервер Express + pg для подключения к PostgreSQL.
  • helper.js содержит CRUD-функции.
  • index.js регистрирует маршруты.
  • Тесты и права БД — критичны для надёжности.

1-line глоссарий:

  • CRUD — операции создания, чтения, обновления и удаления данных.

Social preview (рекомендуется): OG title: CRUD API на Node.js и PostgreSQL OG description: Пошаговое руководство по созданию простого REST CRUD API с Express и PostgreSQL.

Short announcement (для рассылки): Создано простое и понятное руководство по созданию CRUD API на Node.js с PostgreSQL. Шаги включают настройку сервера, подключение pg, реализацию CRUD-функций, маршрутов и рекомендации по безопасности и тестированию.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

RDP: полный гид по настройке и безопасности
Инфраструктура

RDP: полный гид по настройке и безопасности

Android как клавиатура и трекпад для Windows
Гайды

Android как клавиатура и трекпад для Windows

Советы и приёмы для работы с PDF
Документы

Советы и приёмы для работы с PDF

Calibration в Lightroom Classic: как и когда использовать
Фото

Calibration в Lightroom Classic: как и когда использовать

Отключить Siri Suggestions на iPhone
iOS

Отключить Siri Suggestions на iPhone

Рисование таблиц в Microsoft Word — руководство
Office

Рисование таблиц в Microsoft Word — руководство