6.6 KiB
cards
Веб-сервер на C++20 с использованием Boost.Beast и PostgreSQL. Отдаёт случайные записи из таблицы random_data по HTTP API.
Требования
- Компилятор с поддержкой C++20 (GCC 10+, Clang 10+)
- CMake >= 3.14
- PostgreSQL (runtime) + libpq + libpqxx >= 7.0
- Boost (system)
- nlohmann_json 3.x
Установка зависимостей (Debian/Ubuntu):
sudo apt-get install libboost-all-dev libpq-dev libpqxx-dev nlohmann-json3-dev cmake build-essential
Сборка
./configure.sh
Скрипт устанавливает зависимости для Debian/Ubuntu, собирает проект и создаёт deb-пакет.
Или вручную:
mkdir -p build && cd build
cmake ..
make -j"$(nproc)"
cd ..
Бинарник: build/bin/cards
Конфигурация
По умолчанию читает config.json из рабочей директории. Можно указать путь к другому файлу:
./build/bin/cards /path/to/config.json
Для подробного вывода этапов запуска и итоговой конфигурации используйте флаг --debug. Пароль базы данных в таком выводе не раскрывается.
./build/bin/cards --debug
./build/bin/cards --debug /path/to/config.json
Аргументы можно передавать в любом порядке. Программа принимает не более одного пути к файлу конфигурации.
Поля config.json
server
| Поле | Тип | Обязательно |
|---|---|---|
| address | string | да |
| port | int | да |
| threads | int | да |
database
| Поле | Тип | Значение по умолчанию |
|---|---|---|
| host | string | "localhost" |
| port | int | 5432 |
| dbname | string | пустая строка |
| user | string | пустая строка |
| password | string | (пусто) |
Переменные окружения
Переопределяют соответствующие поля config.json:
DB_HOSTDB_PORTDB_NAMEDB_USERDB_PASSWORD
Пример:
DB_PASSWORD=secret ./build/bin/cards
API
| Метод | Путь | Описание |
|---|---|---|
| GET | / |
Случайная запись из таблицы random_data |
| GET | /cards?count=N |
До N случайных записей из таблицы random_data |
| GET | /health |
Проверка состояния сервера |
Параметр count обязателен для /cards, должен быть целым числом и ограничивается диапазоном от 1 до 1000. Если записей в базе меньше запрошенного числа, сервер вернёт все доступные записи. Для выборок до 10 записей применяется обычная стратегия, для бо́льших — рекурсивный SQL-запрос.
Пример ответа GET /
{
"id": 3,
"name": "Gamma",
"text": "Third test record",
"description": "Third test record",
"created_at": "2025-01-01 12:00:00",
"timestamp": 1735732800000000000
}
Пример ответа GET /cards?count=2
{
"data": [
{
"id": 3,
"name": "Gamma",
"text": "Third test record",
"description": "Third test record",
"created_at": "2025-01-01 12:00:00"
},
{
"id": 5,
"name": "Delta",
"text": "Fourth test record",
"description": "Fourth test record",
"created_at": "2025-01-01 12:00:00"
}
],
"count": 2,
"requested_count": 2,
"total_available": 5,
"strategy": "slow",
"timestamp": 1735732800000000000
}
Пример ответа GET /health
{
"status": "ok",
"timestamp": 1735732800000000000
}
База данных
При первом запуске автоматически создаётся таблица random_data. Начальные данные сервер не добавляет: их необходимо загрузить самостоятельно.
Схема таблицы:
CREATE TABLE random_data (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
text TEXT NOT NULL,
description TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
При обновлении существующей базы данных схему нужно мигрировать отдельно:
CREATE TABLE IF NOT EXISTSне изменяет уже созданные таблицы. Например, для предыдущей схемы с полемvalueвыполнитеALTER TABLE random_data RENAME COLUMN value TO text;.
systemd
Юнит-файл: deploy/systemd/cards.service
[Unit]
Description=Cards web server
After=network-online.target
[Service]
Type=simple
User=cards
Group=cards
ExecStart=/usr/bin/cards /etc/cards/config.json
Restart=on-failure
AmbientCapabilities=CAP_NET_BIND_SERVICE
NoNewPrivileges=yes
ProtectSystem=full
ProtectHome=yes
PrivateTmp=yes
Установка вручную:
sudo cp deploy/systemd/cards.service /usr/lib/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now cards
Сборка deb-пакета
cd build
cmake ..
cpack
Результат: cards-1.0.1-Linux.deb
Содержимое deb-пакета
| Путь | Назначение |
|---|---|
/usr/bin/cards |
Исполняемый файл |
/usr/lib/systemd/system/cards.service |
systemd-юнит |
/etc/cards/config.json.example |
Пример конфигурации |
/usr/share/doc/cards/LICENSE |
Лицензия |
Управляющие скрипты
При установке deb-пакета (postinst):
- Создаётся пользователь и группа
cards - Копируется
/etc/cards/config.json.example→/etc/cards/config.json(если нет) - Сервис
cardsвключается и запускается
При удалении (prerm):
- Сервис останавливается и отключается
Завершение работы
- Вручную:
Ctrl+Cилиkillс сигналомSIGTERM - systemd:
systemctl stop cards