Messager is a high-performance, scalable messaging service built with Go. It provides a robust platform for message queuing and delivery, featuring real-time status updates, persistent storage, and reliable message processing capabilities.
- Features
- System Architecture
- Getting Started
- API Reference
- Configuration
- Development
- Logging
- Security
- Contributing
- License
The application exposes a REST API that allows users to create a message by providing content and phone data. Users can then retrieve a list of their messages and control the execution of jobs—starting or stopping them—through the same API.
Once a job is initiated, it periodically updates the status of messages that are in the pending state. These database changes are captured by Debezium and published to a Kafka topic. A Kafka consumer within the application listens for these changes and triggers an HTTP request to the corresponding client.
The metadata returned from the client is then stored in Redis. This eventual consistency architecture ensures resilience against common trade-offs such as:
- The database being updated, but the HTTP request not being sent.
- The HTTP request being sent, but the database not being updated.
- Duplicate requests being triggered.
Thanks to the consumer-based design, the application can scale horizontally by running multiple replicas, enabling faster message processing. The overall architecture is designed with high availability in mind.
The application follows Domain-Driven Design (DDD) principles and applies SOLID principles effectively, using appropriate abstractions and design patterns to ensure extensibility and maintainability. Additionally, by avoiding third-party libraries—including HTTP frameworks—the system reduces external dependencies and increases robustness. Any component can be replaced or modified without disrupting the integrity of other application layers.
- Message Management
- Create and queue messages with validation
- Track message status (PENDING → SENT)
- Phone number validation with international format
- Message content validation (10-255 characters)
- High Performance
- Asynchronous message processing
- Redis caching for sent message info
- Kafka-based message queue
- PostgreSQL for persistent storage
- Real-time CDC with Debezium
- Capture database changes in real-time
- Automatic status updates via Kafka
- Event-driven architecture
- Monitoring & Management
- Health check endpoints
- Structured JSON logging
- Correlation ID tracking
┌─────────────────────────────────────────────────────┐
│ Presentation Layer │
│ ┌─────────────┐ ┌──────────┐ ┌─────────┐ │
│ │ REST API │ │ Jobs │ │ Kafka │ │
│ │ Handlers │ │ Processor│ │Consumer │ │
│ └─────────────┘ └──────────┘ └─────────┘ │
├─────────────────────────────────────────────────────┤
│ Application Layer │
│ ┌─────────────┐ ┌──────────┐ ┌─────────┐ │
│ │ Message │ │ Business │ │ Service │ │
│ │ Services │ │ Logic │ │ Layer │ │
│ └─────────────┘ └──────────┘ └─────────┘ │
├─────────────────────────────────────────────────────┤
│ Domain Layer │
│ ┌─────────────┐ ┌──────────┐ ┌─────────┐ │
│ │ Entities │ │Repository│ │ Domain │ │
│ │ & Models │ │Interface │ │Services │ │
│ └─────────────┘ └──────────┘ └─────────┘ │
├─────────────────────────────────────────────────────┤
│ Infrastructure Layer │
│┌────────┐ ┌─────┐ ┌────────┐ ┌────-─┐ ┌──────────┐ │
││Postgres│ │Redis│ │ Kafka │ │HTTP │ │ Logger │ │
││ DB │ │Cache│ │ Queue │ │Client│ │& Monitor │ │
│└────────┘ └─────┘ └────────┘ └─────-┘ └──────────┘ │
└─────────────────────────────────────────────────────┘
# Check Go version (requires 1.24+)
go version
# Check Docker version
docker --version
docker-compose --version-
Clone and Setup
# Clone repository git clone https://github.com/nemre/messager.git cd messager # Create environment file cp .env.example .env # Initialize Go modules go mod tidy
-
Configure Environment
# Edit .env file with your settings nano .env # Required settings: # - Server configuration (SERVER_*) # - Database credentials (POSTGRESQL_*) # - Redis settings (REDIS_*) # - Kafka configuration (KAFKA_*) # - Client settings (CLIENT_*)
-
Start Services
# Start all services docker-compose up -d # Verify services are running docker-compose ps # Check logs docker-compose logs -f
-
Verify Installation
# Check API health curl http://localhost:2025/health # Should return: # {"status":"green"}
http://localhost:2025/swagger/index.html
curl -X POST http://localhost:2025/messages \
-H "Content-Type: application/json" \
-d '{
"content": "Your message content",
"phone": "+905321234567"
}'# Get PENDING messages
curl http://localhost:2025/messages?status=PENDING
# Get SENT messages
curl http://localhost:2025/messages?status=SENT# Start processing
curl -X POST http://localhost:2025/messages/jobs
# Stop processing
curl -X DELETE http://localhost:2025/messages/jobs# Server Configuration
SERVER_HOST=0.0.0.0
SERVER_PORT=2025
SERVER_ID_HEADER=X-Correlation-ID
# PostgreSQL Configuration
POSTGRESQL_HOST=postgres
POSTGRESQL_PORT=5432
POSTGRESQL_USER=messager
POSTGRESQL_PASSWORD=messager
POSTGRESQL_NAME=messager
# Redis Configuration
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_DB=0
# Job Configuration
JOB_INTERVAL=2m
# Kafka Configuration
KAFKA_BROKERS=kafka:9092
KAFKA_TOPIC=messager.public.messages
KAFKA_GROUP_ID=messager
# Client Configuration
CLIENT_URL=https://api.example.com
CLIENT_TOKEN=your-token
CLIENT_TIMEOUT=5smessager/
├── application/ # Application Services
│ └── service/
│ └── message/ # Message Service Implementation
├── domain/ # Domain Layer
│ └── message/
│ ├── entity.go # Message Entity & Validation
│ ├── repository.go # Repository Interface
│ └── service.go # Service Interface
├── infrastructure/ # Infrastructure Layer
│ ├── client/ # HTTP Client
│ ├── config/ # Configuration
│ ├── database/ # Database Implementations
│ ├── logger/ # Structured Logger
│ ├── persistence/ # Repository Implementations
│ └── server/ # HTTP Server
└── presentation/ # Presentation Layer
├── consumer/ # Kafka Consumers
├── handler/ # HTTP Handlers
└── job/ # Background Jobs
- Structured JSON logs
- Log levels: DEBUG, INFO, WARNING, ERROR, FATAL
- Correlation ID tracking
- Separate stdout/stderr streams
- TLS support
- Token-based authentication
- Input validation
- Rate limiting
- Secure defaults
See SECURITY.md for:
- Supported versions
- Reporting vulnerabilities
- Security update policy
We welcome contributions! Please see:
- Fork the repository
- Create your feature branch
- Commit your changes
- Push to the branch
- Create a Pull Request
This project is licensed under the BSD 3-Clause License - see the LICENSE file for details.

