Backend-сервис платформы мероприятий для практического изучения NoSQL баз данных. Пользователи регистрируются, создают события, оставляют реакции и отзывы, а система строит рекомендации на основе графа предпочтений.
| Категория | Технология |
|---|---|
| Язык | Go 1.25 |
| Сборка и запуск | Docker, Docker Compose, Makefile |
| Документация API | Swagger (swaggo), Postman Collection |
| MongoDB | go.mongodb.org/mongo-driver — пользователи и события (sharded cluster) |
| Cassandra | github.com/gocql/gocql — реакции и отзывы |
| Neo4j | github.com/neo4j/neo4j-go-driver/v5 — граф рекомендаций |
| Redis | github.com/redis/go-redis/v9 — сессии и кэши |
| Путь | Назначение |
|---|---|
cmd/app/ |
Точка входа, инициализация зависимостей и HTTP-роутов |
internal/handler/ |
HTTP-слой: парсинг запросов, cookie-сессии, коды ответов |
internal/service/ |
Бизнес-логика и orchestration между хранилищами |
internal/repository/ |
Доступ к MongoDB, Cassandra, Neo4j, Redis |
internal/model/ |
Доменные модели (User, Event, Review, Reaction) |
internal/session/ |
Хранение сессий в Redis |
internal/config/ |
Загрузка конфигурации из env |
api/ |
Postman-коллекция и YAML-описания запросов |
docs/ |
Swagger-артефакты (swagger.yaml, swagger.json) |
flowchart TD
Client[ClientOrPostman] --> Handlers[HttpHandlers]
Handlers --> Services[BusinessServices]
Services --> Mongo[(MongoDB)]
Services --> Cassandra[(Cassandra)]
Services --> Neo4j[(Neo4j)]
Services --> Redis[(Redis)]
erDiagram
User ||--o{ Event : creates
User ||--o{ EventReaction : makes
User ||--o{ EventReview : writes
Event ||--o{ EventReaction : has
Event ||--o{ EventReview : has
User ||--o{ LIKED : graph_edge
Event ||--o{ LIKED : graph_edge
| Хранилище | Сущности | Назначение |
|---|---|---|
| MongoDB | users, events |
Основные документы, фильтрация и индексы |
| Cassandra | event_reactions, event_reviews |
Высокочастотные записи реакций и отзывов |
| Neo4j | узлы User, Event, ребро LIKED |
Коллаборативные рекомендации |
| Redis | сессии, кэши реакций/отзывов/рекомендаций | Быстрый доступ и TTL-кэширование |
Поток запроса: Client → Handler → Service → Repository → NoSQL → ответ.
- Регистрация и аутентификация — пользователь регистрируется (
POST /users) или входит (POST /auth/login); сессия хранится в cookieX-Session-Id(Redis). - Анонимная сессия —
POST /sessionсоздаёт или продлевает сессию без привязки к пользователю. - Создание и поиск событий — авторизованный пользователь создаёт событие; список поддерживает фильтры по title, category, price, city, дате, организатору.
- Редактирование события — организатор обновляет category, price, city через
PATCH /events/{id}. - Реакции — like/dislike сохраняются в Cassandra; агрегаты по title кэшируются в Redis.
- Отзывы — create/list/patch в Cassandra; один отзыв на пользователя на событие; агрегаты рейтинга кэшируются в Redis.
- Рекомендации —
GET /recommendationsиспользует Neo4j-граф и cache-aside в Redis. - Мониторинг —
GET /healthи Swagger UI на/swagger/.
- Swagger UI (после запуска): http://localhost:8080/swagger/
- Postman-коллекция: api/eventhub.postman_collection.json
Аутентификация — cookie X-Session-Id. Рекомендуемый порядок вызовов в Postman:
Session → Create or Refresh SessionUsers → Register UserилиAuth → LoginEvents → Create Event→ реакции / отзывы / рекомендации
Healthcheck
GET /health{"status":"ok"}Регистрация пользователя
POST /users
Content-Type: application/json
{
"full_name": "Demo User",
"username": "demo.user",
"password": "demo-password"
}Ответ: 201 Created (тело пустое, в Set-Cookie — X-Session-Id).
Создание события
POST /events
Content-Type: application/json
Cookie: X-Session-Id=<session_id>
{
"title": "NDBX Meetup",
"address": "Nevsky Prospect 1",
"started_at": "2026-06-01T18:00:00Z",
"finished_at": "2026-06-01T20:00:00Z",
"description": "Community meetup"
}{"id": "665f1a2b3c4d5e6f7a8b9c0d"}Список событий с агрегатами
GET /events?include=reactions,reviews&limit=10&offset=0{
"events": [
{
"id": "665f1a2b3c4d5e6f7a8b9c0d",
"title": "NDBX Meetup",
"category": "meetup",
"price": 500,
"description": "Community meetup",
"location": {"address": "Nevsky Prospect 1", "city": "Saint Petersburg"},
"created_at": "2026-05-01T12:00:00Z",
"created_by": "665f0a1b2c3d4e5f6a7b8c9d",
"started_at": "2026-06-01T18:00:00Z",
"finished_at": "2026-06-01T20:00:00Z",
"reactions": {"likes": 3, "dislikes": 1},
"reviews": {"count": 2, "rating": 4.5}
}
],
"count": 1
}Рекомендации
GET /recommendations
Cookie: X-Session-Id=<session_id>{
"events": [
{
"id": "665f2b3c4d5e6f7a8b9c0d1e",
"title": "Go Conference",
"category": "meetup",
"price": 0,
"location": {"address": "ITMO University"},
"started_at": "2026-07-15T10:00:00Z",
"finished_at": "2026-07-15T18:00:00Z"
}
]
}| Метод | Путь | Описание |
|---|---|---|
| GET | /health |
Проверка доступности |
| GET | /swagger/ |
Swagger UI |
| POST | /session |
Создать/обновить сессию |
| POST | /users |
Регистрация |
| GET | /users |
Список пользователей |
| GET | /users/{id} |
Пользователь по ID |
| GET | /users/{id}/events |
События пользователя |
| POST | /auth/login |
Вход |
| POST | /auth/logout |
Выход |
| POST | /events |
Создать событие |
| GET | /events |
Список событий |
| GET | /events/{id} |
Событие по ID |
| PATCH | /events/{id} |
Обновить событие |
| GET | /recommendations |
Рекомендации |
| POST | /events/{id}/like |
Лайк |
| POST | /events/{id}/dislike |
Дизлайк |
| POST | /events/{id}/reviews |
Создать отзыв |
| GET | /events/{id}/reviews |
Список отзывов |
| PATCH | /events/{id}/reviews/{review_id} |
Обновить отзыв |
- Docker и Docker Compose
- Make (GNU Make)
- Go 1.25+ (для локального запуска тестов)
- Клонируйте репозиторий и перейдите в корень проекта.
- Проверьте файл .env.local — порты, учётные данные БД, TTL кэшей.
- Запустите окружение:
make run- Проверьте статус контейнеров:
make services- Убедитесь, что API отвечает:
curl http://localhost:8080/health- Откройте Swagger: http://localhost:8080/swagger/ или импортируйте api/eventhub.postman_collection.json в Postman.
make stop # остановить контейнеры
make clean # остановить и удалить тома (полная очистка данных)Для отладки в foreground: make rund.
Переменные окружения задаются в .env.local и читаются приложением через internal/config/config.go.
| Переменная | Описание | Значение по умолчанию |
|---|---|---|
APP_HOST |
Хост HTTP-сервера | 0.0.0.0 |
APP_PORT |
Порт HTTP-сервера | 8080 |
APP_USER_SESSION_TTL |
TTL сессии пользователя (сек) | 60 |
APP_LIKE_TTL |
TTL кэша реакций (сек) | 60 |
APP_EVENT_REVIEWS_TTL |
TTL кэша отзывов (сек) | 120 |
APP_RECOMMENDATIONS_TTL |
TTL кэша рекомендаций (сек) | 60 |
| Переменная | Описание | Значение по умолчанию |
|---|---|---|
REDIS_HOST |
Хост Redis | redis |
REDIS_PORT |
Порт Redis | 6379 |
REDIS_PASSWORD |
Пароль Redis | (пусто) |
REDIS_DB |
Номер БД Redis | 0 |
| Переменная | Описание | Значение по умолчанию |
|---|---|---|
MONGODB_HOST |
Хост mongos | mongos |
MONGODB_PORT |
Порт mongos | 27017 |
MONGODB_DATABASE |
Имя базы | eventhub |
MONGODB_USER |
Пользователь | eventhub |
MONGODB_PASSWORD |
Пароль | eventhub |
MONGODB_INIT_SLEEP_SECONDS |
Задержка инициализации кластера | 10 |
MONGODB_CONFIG_REPLICA_SET |
Имя config replica set | cfg-rs |
MONGODB_CONFIG1_PORT |
Порт config node 1 | 27111 |
MONGODB_CONFIG2_PORT |
Порт config node 2 | 27112 |
MONGODB_CONFIG3_PORT |
Порт config node 3 | 27113 |
MONGODB_SHARD1_NAME |
Имя shard 1 | shard1 |
MONGODB_SHARD1_REPLICA_SET |
Replica set shard 1 | shard1-rs |
MONGODB_SHARD1_NODE1_PORT |
Порт shard1 node 1 | 27211 |
MONGODB_SHARD1_NODE2_PORT |
Порт shard1 node 2 | 27212 |
MONGODB_SHARD1_NODE3_PORT |
Порт shard1 node 3 | 27213 |
MONGODB_SHARD2_NAME |
Имя shard 2 | shard2 |
MONGODB_SHARD2_REPLICA_SET |
Replica set shard 2 | shard2-rs |
MONGODB_SHARD2_NODE1_PORT |
Порт shard2 node 1 | 27311 |
MONGODB_SHARD2_NODE2_PORT |
Порт shard2 node 2 | 27312 |
MONGODB_SHARD2_NODE3_PORT |
Порт shard2 node 3 | 27313 |
| Переменная | Описание | Значение по умолчанию |
|---|---|---|
CASSANDRA_HOSTS |
Хосты (через запятую) | cassandra |
CASSANDRA_PORT |
Порт CQL | 9042 |
CASSANDRA_USERNAME |
Имя пользователя | (пусто) |
CASSANDRA_PASSWORD |
Пароль | (пусто) |
CASSANDRA_KEYSPACE |
Keyspace | testkeyspace |
CASSANDRA_CONSISTENCY |
Уровень консистентности | ONE |
CASSANDRA_CLUSTER_NAME |
Имя кластера | EventHubCluster |
CASSANDRA_DC |
Datacenter | dc1 |
CASSANDRA_RACK |
Rack | rack1 |
CASSANDRA_MAX_HEAP_SIZE |
Max heap | 512M |
CASSANDRA_HEAP_NEWSIZE |
New gen heap | 128M |
CASSANDRA_MEM_LIMIT |
Лимит памяти контейнера | 1g |
CASSANDRA_MEM_RESERVATION |
Резерв памяти | 512m |
| Переменная | Описание | Значение по умолчанию |
|---|---|---|
NEO4J_URL |
Bolt URL | bolt://neo4j:7687 |
NEO4J_USERNAME |
Имя пользователя | neo4j |
NEO4J_PASSWORD |
Пароль | password |
NEO4J_BOLT_PORT |
Bolt-порт | 7687 |
NEO4J_HTTP_PORT |
HTTP-порт браузера | 7474 |
go test ./...Покрыты сервисы с mock-репозиториями:
- internal/service/user_service_test.go — регистрация, логин, валидация запросов
- internal/service/event_service_test.go — создание событий, фильтры, реакции, отзывы, рекомендации
Интеграционные и автоматизированные end-to-end тесты в репозитории не реализованы; проверка API выполняется через Postman-коллекцию и CI autograder (.github/workflows/eventhub.yml).
make run- Импортировать api/eventhub.postman_collection.json
- Выполнить запросы по порядку: Session → Register/Login → Events
Каждая СУБД решает свою задачу: MongoDB — документы, Cassandra — write-heavy реакции/отзывы, Neo4j — граф рекомендаций, Redis — сессии и кэш.
Сессия передаётся через HttpOnly cookie X-Session-Id. В Postman переменная {{session_id}} заполняется автоматически test-скриптами.
TLDR: запуск через make run, долго стартует - поднимается sharded MongoDB cluster, Cassandra, Neo4j и init-скрипты. Дождитесь healthy у всех сервисов (make services).
Swagger: после запуска — http://localhost:8080/swagger/. Спецификация генерируется swaggo в docs/swagger.yaml.
Как сбросить все данные?
drop database :)
make clean удалит тома Docker и очистит состояние всех БД.