Skip to content

netology-code/goprod-diplom

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Advanced Blog Management System - Reference Implementation

Полная реализация дипломного проекта на Go для разработки полнофункциональной системы управления блогом с REST API, JWT аутентификацией, PostgreSQL и планировщиком отложенной публикации.

📋 Содержание

О проекте

Advanced Blog Management System - это полная реализация дипломного проекта для студентов, изучающих Go, REST API и работу с базами данных.

Проект включает:

  • ✅ Управление пользователями (регистрация, вход)
  • ✅ Управление постами (создание, редактирование, удаление)
  • ✅ Управление комментариями (создание, редактирование, удаление)
  • ✅ JWT аутентификация и авторизация
  • ✅ Отложенная публикация постов с автоматическим планировщиком
  • ✅ Логирование всех запросов с уникальными request_id
  • ✅ Кеширование GET-запросов (5 минут по умолчанию)
  • ✅ CORS поддержка
  • ✅ Swagger документация
  • ✅ Docker контейнеризация
  • ✅ Полное покрытие тестами

Структура проекта

advanced-blog-management-system/
├── cmd/api/
│   └── main.go                 # Точка входа приложения
├── docs/                       # Swagger документация
│   ├── docs.go
│   ├── swagger.json
│   └── swagger.yaml
├── internal/
│   ├── apperrors/              # Ошибки приложения
│   │   └── errors.go
│   ├── handler/                # HTTP обработчики
│   │   ├── auth_handler.go
│   │   ├── post_handler.go
│   │   ├── comment_handler.go
│   │   ├── health.go
│   │   └── *_test.go
│   ├── middleware/             # HTTP middleware
│   │   ├── auth.go
│   │   ├── logging.go
│   │   ├── cors.go
│   │   ├── cache.go
│   │   ├── recovery.go
│   │   └── *_test.go
│   ├── model/                  # Модели данных
│   │   ├── models.go
│   │   └── *_test.go
│   ├── repository/             # Слой доступа к БД
│   │   ├── interfaces.go
│   │   ├── user_repo.go
│   │   ├── post_repo.go
│   │   ├── comment_repo.go
│   │   └── *_test.go
│   └── service/                # Бизнес-логика
│       ├── user_service.go
│       ├── post_service.go
│       ├── comment_service.go
│       ├── scheduler.go
│       └── *_test.go
├── pkg/
│   ├── auth/                   # Утилиты аутентификации
│   │   ├── jwt.go
│   │   ├── password.go
│   │   └── *_test.go
│   └── database/               # Утилиты БД
│       ├── db.go
│       └── *_test.go
├── migrations/                 # SQL миграции
│   ├── 001_init_schema.sql
│   ├── 002_add_foreign_keys.sql
│   └── 003_create_indexes.sql
├── .env.example                # Пример конфигурации
├── docker-compose.yml          # Docker Compose
├── Dockerfile                  # Docker образ
├── go.mod                      # Зависимости проекта
└── README.md

Технологический стек

  • Язык: Go 1.24.5
  • Веб-фреймворк: Chi Router
  • База данных: PostgreSQL 15
  • Аутентификация: JWT (golang-jwt)
  • Хеширование: bcrypt (golang.org/x/crypto)
  • Документация: Swagger/OpenAPI
  • Контейнеризация: Docker, Docker Compose
  • Валидация: go-playground/validator

Быстрый старт

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

  • Go 1.24.5 или выше
  • Docker и Docker Compose
  • Git

1. Подготовка окружения

# Клонировать репозиторий
git clone https://github.com/tim-zab/advanced-blog-management-system.git
cd advanced-blog-management-system

# Скопировать конфигурацию
cp .env.example .env

# Установить Go зависимости
go mod download

2. Запуск БД

# Запустить PostgreSQL в Docker
docker-compose up -d db

# Подождать пока БД запустится (примерно 15 секунд)
docker-compose logs db

3. Разработка и запуск

# Запустить приложение с race detector (рекомендуется)
go run -race ./cmd/api/main.go

# Или просто запустить
go run cmd/api/main.go

# Или собрать и запустить
go build -o api ./cmd/api/main.go
./api

Приложение будет доступно на http://localhost:8080

4. Docker контейнеризация

# Запустить всё через Docker Compose
docker-compose up --build

# Остановить
docker-compose down

# Очистить данные БД
docker-compose down -v

После запуска:

  • API доступен: http://localhost:8080
  • Swagger документация: http://localhost:8080/swagger/index.html
  • JSON документация: http://localhost:8080/swagger/doc.json

Разработка

Что уже готово ✅

  • Полная реализация всех компонентов
  • Структура проекта и директории
  • Модели данных (User, Post, Comment)
  • Интерфейсы и реализация репозиториев
  • SQL миграции (создание таблиц, внешних ключей и индексов)
  • Функции хеширования паролей
  • JWT генерация и валидация
  • Middleware (аутентификация, логирование, CORS, кеширование, обработка ошибок)
  • Все HTTP эндпоинты
  • Планировщик отложенной публикации
  • Swagger документация
  • Полное покрытие тестами
  • docker-compose.yml и Dockerfile

API эндпоинты

Публичные эндпоинты

GET    /api/health                     # Проверка здоровья приложения
POST   /api/register                   # Регистрация нового пользователя
POST   /api/login                      # Вход пользователя
GET    /api/posts                      # Получить все посты (кешируется)
GET    /api/posts/{id}                 # Получить пост по ID (кешируется)
GET    /api/posts/{postId}/comments    # Получить комментарии к посту (кешируется)

Защищенные эндпоинты (требуют Authorization: Bearer )

POST   /api/posts                      # Создать пост
PUT    /api/posts/{id}                 # Обновить пост
DELETE /api/posts/{id}                 # Удалить пост
POST   /api/posts/{postId}/comments    # Добавить комментарий
PUT    /api/comments/{id}              # Обновить комментарий
DELETE /api/comments/{id}              # Удалить комментарий

Планировщик отложенной публикации

Как работает

  1. При создании поста с указанием publish_at в будущем, пост сохраняется в статусе "draft"
  2. Планировщик каждые 30 секунд проверяет посты со статусом "draft" и временем публикации <= текущего времени
  3. Найденные посты автоматически публикуются (статус меняется на "published", поле publish_at устанавливается в NULL)
  4. Обработка постов происходит конкурентно с использованием worker pool (5 воркеров по умолчанию)
  5. Все операции логируются для отслеживания процесса

Настройки планировщика

  • Интервал проверки: 30 секунд (настраивается в коде)
  • Количество воркеров: 5 (настраивается в коде)
  • Планировщик корректно завершается при остановке сервиса (graceful shutdown)

Примеры использования

Создание поста с отложенной публикацией:

curl -X POST http://localhost:8080/api/posts \
  -H "Authorization: Bearer <токен>" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Отложенный пост",
    "content": "Этот пост будет опубликован в указанное время",
    "publish_at": "2025-12-31T23:59:59Z"
  }'

Проверка статуса поста (будет "draft" до указанного времени):

curl http://localhost:8080/api/posts/2 \
  -H "Authorization: Bearer <токен>"

Тестирование

Unit тесты

# Запустить все тесты
go test ./...

# Запустить с подробным выводом
go test -v ./...

# Проверить на race conditions
go test -race ./...

# Посмотреть покрытие тестами
go test ./... -cover

Примеры curl команд

1. Health check

curl http://localhost:8080/api/health

Ответ:

{"status":"ok"}

2. Регистрация пользователя

curl -X POST http://localhost:8080/api/register \
  -H "Content-Type: application/json" \
  -d '{
    "username": "testuser",
    "email": "test@example.com",
    "password": "password123"
  }'

Ответ (HTTP/1.1 201 Created):

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "expires_at": "2025-12-11T10:11:29.1543196+03:00",
  "user": {
    "id": 1,
    "username": "testuser",
    "email": "test@example.com",
    "created_at": "2025-12-10T10:11:29.1493162+03:00"
  }
}

3. Авторизация (получение JWT)

curl -X POST http://localhost:8080/api/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "test@example.com",
    "password": "password123"
  }'

Ответ (HTTP/1.1 200 OK):

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "expires_at": "2025-12-11T10:14:56.4065894+03:00",
  "user": {
    "id": 1,
    "username": "testuser",
    "email": "test@example.com",
    "created_at": "2025-12-10T10:11:29.149316Z"
  }
}

4. Создание поста

curl -X POST http://localhost:8080/api/posts \
  -H "Authorization: Bearer <токен>" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Тестовый пост",
    "content": "Содержание поста"
  }'

Ответ (HTTP/1.1 201 Created):

{
  "id": 1,
  "title": "Тестовый пост",
  "content": "Содержание поста",
  "author_id": 1,
  "status": "published",
  "created_at": "2025-12-10T10:17:23.9918739+03:00",
  "updated_at": "2025-12-10T10:17:23.9918739+03:00"
}

5. Получение всех постов

curl http://localhost:8080/api/posts

Ответ (HTTP/1.1 200 OK):

{
  "posts": [
    {
      "id": 1,
      "title": "Тестовый пост",
      "content": "Содержание поста",
      "author_id": 1,
      "status": "published",
      "created_at": "2025-12-10T10:17:23.991874Z",
      "updated_at": "2025-12-10T10:17:23.991874Z"
    }
  ],
  "total": 1,
  "limit": 10,
  "offset": 0
}

6. Добавление комментария

curl -X POST http://localhost:8080/api/posts/1/comments \
  -H "Authorization: Bearer <токен>" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Отличный пост!"
  }'

Ответ (HTTP/1.1 201 Created):

{
  "id": 1,
  "content": "Отличный пост!",
  "post_id": 1,
  "author_id": 1,
  "created_at": "2025-12-10T12:21:53.7135501+03:00",
  "updated_at": "2025-12-10T12:21:53.7135501+03:00"
}

Документация

Swagger

Интерактивная документация доступна на:

  • http://localhost:8080/swagger/index.html - веб-интерфейс Swagger UI
  • http://localhost:8080/swagger/doc.json - JSON документация

Архитектура приложения

Проект использует чистую архитектуру с разделением ответственности:

┌─────────────────┐
│  HTTP Requests  │
└────────┬────────┘
         │
┌────────▼────────────────────────┐
│ Middleware (Auth, Logging, CORS)│
└────────┬────────────────────────┘
         │
┌────────▼─────────────┐
│ Handlers (HTTP API)  │ ← Парсинг JSON, валидация, HTTP коды
└────────┬─────────────┘
         │
┌────────▼──────────────┐
│ Services (Business)   │ ← Бизнес-логика, валидация, права
└────────┬──────────────┘
         │
┌────────▼─────────────┐
│ Repositories (Data)  │ ← SQL запросы, работа с БД
└────────┬─────────────┘
         │
┌────────▼────────┐
│  PostgreSQL DB  │
└─────────────────┘

Docker образы

  • API: golang:1.24-alpine → компиляция → alpine:latest (многоэтапная сборка)
  • База данных: postgres:15
  • Сеть: bridge с именем blog-network
  • Том: postgres_data для сохранения данных

Миграции

  1. 001_init_schema.sql - создаёт таблицы users, posts, comments
  2. 002_add_foreign_keys.sql - добавляет внешние ключи для целостности данных
  3. 003_create_indexes.sql - создаёт индексы для улучшения производительности

Миграции запускаются автоматически при старте приложения.

Конфигурация

Переменные окружения задаются в файле .env:

# Database
DB_HOST=localhost
DB_PORT=5432
DB_USER=postgres
DB_PASSWORD=postgres
DB_NAME=blog_db
DB_SSLMODE=disable

# JWT
JWT_SECRET=your-secret-key-change-in-production

# Server
SERVER_HOST=0.0.0.0
SERVER_PORT=8080

# Cache
CACHE_TTL=300

# Scheduler
SCHEDULER_INTERVAL=30
SCHEDULER_WORKERS=5

# Environment
ENV=development

Возможности системы

Логирование

Каждый запрос логируется в формате:

20250405100000.123-456 | 172.18.0.1:54321 | POST /api/posts | 201 | 12.345ms

Где:

  • 20250405100000.123-456 - уникальный request_id
  • 172.18.0.1:54321 - IP адрес клиента
  • POST /api/posts - метод и путь
  • 201 - HTTP статус код
  • 12.345ms - время обработки

Кеширование

GET-запросы кешируются на 5 минут (настраивается в конфиге):

  • /api/posts
  • /api/posts/{id}
  • /api/posts/{postId}/comments

Безопасность

  • JWT-аутентификация с HS256
  • CORS разрешён для всех источников (можно настроить)
  • Лимит одновременных запросов: 100
  • Восстановление после паник (Recovery middleware)
  • Параметризованные SQL-запросы (защита от SQL injection)
  • Хеширование паролей с bcrypt

Тесты и покрытие

Приложение покрыто тестами:

Пакет Покрытие
cmd/api 18.6%
internal/handler 92.8%
internal/middleware 51.9%
internal/model 100.0%
internal/repository 62.2%
internal/service 76.1%
pkg/auth 92.0%
pkg/database 92.4%

Для запуска тестов:

# Запустить все тесты
go test ./... -count=1

# Просмотреть покрытие
go test ./... -cover

Примечание: Для запуска теста TestNewPostgresDB требуется наличие тестовой БД testdb или комментирование теста в pkg/database/init_test.go.

Полезные команды

# Скачать и обновить зависимости
go mod download
go mod tidy

# Запустить приложение
go run -race ./cmd/api/main.go

# Собрать приложение
go build -o api ./cmd/api/main.go

# Запустить тесты
go test ./... -v

# Просмотреть логи БД
docker-compose logs db -f

# Подключиться к БД
docker-compose exec db psql -U postgres -d blog_db

# Остановить все сервисы
docker-compose down

# Очистить данные БД
docker-compose down -v

SQL запросы для ручного тестирования

-- Подключиться к БД
docker-compose exec db psql -U postgres -d blog_db

-- Просмотреть таблицы
\dt

-- Просмотреть пользователей
SELECT id, username, email, created_at FROM users;

-- Просмотреть посты
SELECT id, title, status, author_id, created_at FROM posts;

-- Просмотреть комментарии
SELECT id, content, post_id, author_id, created_at FROM comments;

-- Проверить посты в статусе draft
SELECT id, title, status, publish_at FROM posts WHERE status = 'draft';

Критерии успеха

  • ✅ Приложение запускается без ошибок
  • ✅ Все 13+ API эндпоинтов работают
  • ✅ JWT аутентификация работает правильно
  • ✅ Пользователи могут редактировать только свои посты/комментарии
  • ✅ Планировщик отложенной публикации работает
  • ✅ Тесты проходят (go test ./...)
  • ✅ Нет SQL injection уязвимостей
  • ✅ Правильные HTTP статус коды
  • ✅ Логирование работает
  • ✅ Кеширование работает
  • ✅ Приложение работает в Docker контейнере

Частые вопросы

Q: Как добавить нового пользователя вручную?
A: Используйте эндпоинт POST /api/register с валидными данными.

Q: Как получить JWT токен?
A: Отправьте POST /api/login с email и пароль - токен вернется в ответе.

Q: Что делать если БД не подключается?
A: Проверьте что docker-compose up запущен и подождите 15-20 секунд.

Q: Как сбросить БД?
A: Выполните docker-compose down -v для удаления всех данных.

Q: Как отсладжить проблемы с планировщиком?
A: Проверьте логи приложения - планировщик выводит информацию о каждой попытке публикации.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published