Backend API for MPB Blog Platform, built with Go + Fiber + PostgreSQL + JWT.
Implements secure user registration, login, JWT-based authentication, and blog post management with event-driven architecture.
-
Authentication & Authorization
- User registration and login with JWT tokens
- JWT-based authentication middleware
- Token refresh mechanism
-
Blog Posts Management
- Full CRUD operations for posts
- Post ownership validation
- Post attachments (images, files) via S3
- Real-time metrics: likes and views tracking
- Redis-based caching for hot data
-
Comments System
- Create, update, and delete comments on posts
- Comment attachments support
- Nested comment structure
-
Event-Driven Architecture
- Watermill for event publishing/subscribing
- Asynchronous metrics synchronization (Redis β PostgreSQL)
- Event types:
post.viewed,post.liked,post.unliked
-
Infrastructure
- PostgreSQL for persistent data storage
- Redis for real-time metrics and caching
- AWS S3 for file storage
- Docker & Docker Compose for easy deployment
- Database migrations with Goose
- CI/CD with GitHub Actions
- Integrated Swagger documentation
- Input validation via generics + go-playground/validator
| Component | Technology/Library |
|---|---|
| Web Framework | Fiber v2 |
| DB Access | sqlx |
| Database | PostgreSQL 15+ |
| Cache/Metrics | Redis 7+ |
| File Storage | AWS S3 |
| JWT Auth | golang-jwt/jwt/v5 |
| Validation | go-playground/validator/v10 |
| Documentation | fiber-swagger |
| Migrations | goose |
| Event Bus | watermill |
| Containerization | Docker & Docker Compose |
- Go 1.25+
- PostgreSQL 15+
- Redis 7+ (for metrics and caching)
- Docker and Docker Compose (recommended for development)
- AWS Account (optional, for S3 file storage)
-
Clone the repository:
git clone <repository-url> cd mpb
-
Create
.envfile:cp .env_example .env # Edit .env with your values -
Start services:
docker-compose up -d
This will:
- Start PostgreSQL database
- Start Redis server
- Run migrations automatically
- Start the application on
http://localhost:8000
-
View logs:
docker-compose logs -f app
-
Access Swagger documentation:
- Open
http://localhost:8000/swagger/index.html
- Open
-
Install dependencies:
go mod download
-
Start PostgreSQL (or use docker-compose):
docker-compose up -d postgres
-
Set environment variables:
export DSN="postgres://mpb:mpb_pas@localhost:5432/mpb_db?sslmode=disable" export REDIS_ADDR="localhost:6379" export JWT_SECRET="your-secret-key-here" export JWT_TTL="24h" # Optional: for S3 file storage export AWS_REGION="us-east-1" export AWS_BUCKET="your-bucket-name"
-
Run migrations:
make migrate-up # or go run ./cmd/migrate.go -
Run the application:
make run # or go run ./cmd/main.go
make help # Show all available commands
make build # Build the application
make run # Run the application
make test # Run tests
make test-coverage # Run tests with coverage report
make lint # Run linter (requires golangci-lint)
make clean # Clean build artifacts
make dev # Start development environmentmake migrate-up # Run migrations
make migrate-down # Rollback last migration
make migrate-status # Show migration statusmake swaggerdocker build -t mpb:latest .docker run -d \
-p 8000:8000 \
-e DSN="postgres://mpb:mpb_pas@host.docker.internal:5432/mpb_db?sslmode=disable" \
-e JWT_SECRET="your-secret-key" \
-e JWT_TTL="24h" \
mpb:latest# Start all services
docker-compose up -d
# Stop all services
docker-compose down
# View logs
docker-compose logs -f app
# Rebuild and restart
docker-compose up -d --build# Run all tests
make test
# Run tests with coverage
make test-coverageThe project includes GitHub Actions workflows:
-
CI Pipeline (
.github/workflows/ci.yml):- Linting with golangci-lint
- Running tests with PostgreSQL service
- Building the application
- Building and pushing Docker images
- Security scanning with Gosec and Trivy
-
CodeQL Analysis (
.github/workflows/codeql.yml):- Automated code security analysis
POST /api/auth/register- Register new userPOST /api/auth/login- Login and get JWT token
GET /api/posts- List all active postsGET /api/posts/{id}- Get post by ID (increments view count)POST /api/posts- Create new post (requires auth)PUT /api/posts/{id}- Update post (requires auth, owner only)DELETE /api/posts/{id}- Delete post (requires auth, owner only)POST /api/posts/{id}/like- Like a post (requires auth)DELETE /api/posts/{id}/unlike- Unlike a post (requires auth)
POST /api/posts/{id}/attachments- Upload attachment to post (requires auth, owner only)GET /api/posts/{id}/attachments- Get all attachments for a postDELETE /api/posts/{id}/attachments/{attachmentId}- Delete attachment (requires auth, owner only)
GET /api/posts/{id}/comments- Get all comments for a postPOST /api/posts/{id}/comments- Create comment on post (requires auth)PUT /api/comments/{id}- Update comment (requires auth, owner only)DELETE /api/comments/{id}- Delete comment (requires auth, owner only)
POST /api/comments/{id}/attachments- Upload attachment to comment (requires auth, owner only)GET /api/comments/{id}/attachments- Get all attachments for a commentDELETE /api/comments/{id}/attachments/{attachmentId}- Delete attachment (requires auth, owner only)
GET /swagger/*- Swagger UI
| Variable | Description | Default | Required |
|---|---|---|---|
DSN |
PostgreSQL connection string | postgres://mpb:mpb_pas@localhost:5432/mpb_db?sslmode=disable |
Yes |
REDIS_ADDR |
Redis server address | localhost:6379 |
Yes |
JWT_SECRET |
Secret key for JWT signing | - | Yes |
JWT_TTL |
JWT token TTL | 24h |
No |
AWS_REGION |
AWS region for S3 | - | No* |
AWS_BUCKET |
AWS S3 bucket name | - | No* |
* Required only if using S3 file storage
mpb/
βββ cmd/
β βββ main.go # Application entry point
β βββ migrate.go # Migration tool
β βββ healthcheck/ # Health check utility
βββ configs/
β βββ config.go # Configuration loading
βββ internal/
β βββ app/ # Application initialization
β βββ auth/ # Authentication module
β β βββ dto/ # Auth DTOs
β βββ posts/ # Posts module
β β βββ dto/ # Post DTOs
β β βββ events.go # Event definitions
β β βββ metrics_service.go # Redis metrics service
β β βββ metrics_consumer.go # Event consumer for sync
β βββ comments/ # Comments module
β β βββ dto/ # Comment DTOs
β βββ post_attachments/ # Post attachments module
β βββ comments_attachments/ # Comment attachments module
β βββ user/ # User model
βββ migrations/ # Database migrations (Goose)
βββ pkg/
β βββ db/ # Database connection (sqlx)
β βββ redis/ # Redis client wrapper
β βββ s3/ # AWS S3 client
β βββ errors_constant/ # Error constants
β βββ middleware/ # HTTP middleware (JWT, validation)
β βββ security/ # Security utilities (hashing)
βββ docs/ # Swagger documentation
βββ Dockerfile # Docker build configuration
βββ docker-compose.yml # Docker Compose configuration
βββ Makefile # Build automation
βββ go.mod # Go dependencies
The application follows a layered architecture with event-driven components:
- Handler Layer: HTTP request/response handling
- Service Layer: Business logic
- Repository Layer: Data access (PostgreSQL)
- Event Layer: Asynchronous event processing (Watermill)
- Cache Layer: Redis for hot data (likes, views)
-
Metrics (Likes/Views):
- User action β Redis (immediate) β Event published β PostgreSQL (async sync)
-
Posts/Comments:
- User action β PostgreSQL β Response
-
Attachments:
- User upload β S3 β Metadata saved to PostgreSQL
For detailed architecture documentation, see ARCHITECTURE.md.
We welcome contributions! Please see CONTRIBUTING.md for guidelines.
This project is licensed under the MIT License.