A multi-channel notification system built with Spring Boot, featuring email, SMS, push, and in-app notifications.
- Multi-Channel Support: Email, SMS, Push, and In-App notifications
- Rate Limiting: Token bucket algorithm using Redis
- Template System: Reusable message templates with variable substitution
- Async Processing: Kafka-based message queue for reliable delivery
- Retry Mechanism: Exponential backoff for failed notifications
- Priority Queue: HIGH, MEDIUM, LOW priority processing
- Event Deduplication: Prevents duplicate notifications using Redis-backed event ID tracking
- RESTful API: Well-documented endpoints with Swagger UI
โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ
โ API Layer โโโโโโถโ Service Layer โโโโโโถโ Repository โ
โ (Controllers) โ โ (Business Logic)โ โ (Database) โ
โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโฌโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ
โ
โโโโโโโโโโโโโโผโโโโโโโโโโโโโ
โผ โผ โผ
โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ
โ Kafka โ โ Redis โ โ Channels โ
โ (Queue) โ โ (Cache) โ โ(Handlers)โ
โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ
- Java 17 - Modern LTS version
- Spring Boot 3.2 - Application framework
- PostgreSQL 15 - Primary database
- Redis 7 - Rate limiting & caching
- Apache Kafka - Message queue
- Docker Compose - Local development
- Java 17+
- Docker & Docker Compose
- Maven 3.8+
# Start PostgreSQL, Redis, Kafka
docker-compose up -d# Using Maven
./mvnw spring-boot:run
# Or build and run JAR
./mvnw clean package
java -jar target/notification-system-1.0.0.jar- Swagger UI: http://localhost:8080/swagger-ui.html
- API Docs: http://localhost:8080/v3/api-docs
- Health Check: http://localhost:8080/api/v1/health
- Kafka UI: http://localhost:8090
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/v1/notifications |
Send a notification |
| POST | /api/v1/notifications/bulk |
Send bulk notifications |
| GET | /api/v1/notifications/{id} |
Get notification by ID |
| GET | /api/v1/notifications/user/{userId} |
Get user's notifications |
| GET | /api/v1/notifications/user/{userId}/unread-count |
Get unread count |
| PATCH | /api/v1/notifications/{id}/read |
Mark as read |
| PATCH | /api/v1/notifications/user/{userId}/read-all |
Mark all as read |
The notification system implements a robust event deduplication mechanism to prevent duplicate notifications from being sent, even in distributed environments where network issues or retries might cause the same event to be processed multiple times.
- Event ID Tracking: Clients can provide a unique
eventIdin notification requests - Redis-Based Storage: Event IDs are stored in Redis with a configurable TTL (24 hours by default)
- Duplicate Detection: Before processing any notification, the system checks if the event ID has been seen recently
- Graceful Handling: If a duplicate is detected, the request is discarded with a clear error response
Include an eventId in your notification request:
curl -X POST http://localhost:8080/api/v1/notifications \
-H "Content-Type: application/json" \
-d '{
"userId": "550e8400-e29b-41d4-a716-446655440001",
"channel": "EMAIL",
"eventId": "order-confirmation-12345",
"subject": "Order Confirmed",
"content": "Your order has been confirmed!"
}'- Idempotent Operations: Same event ID sent multiple times results in only one notification
- Distributed Safety: Works across multiple application instances
- Configurable TTL: Event IDs automatically expire to prevent memory bloat
- Backward Compatible:
eventIdis optional - existing clients continue to work - Fast Lookups: Redis provides O(1) lookup performance
notification:
dedupe:
ttl-seconds: 86400 # 24 hours- Service:
DeduplicationServicehandles event tracking - Storage: Redis keys follow pattern
event:{eventId} - TTL: Configurable expiration prevents infinite growth
- Thread-Safe: Redis operations are atomic
- Monitoring: Logs duplicate detection for observability
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/v1/templates |
Create template |
| GET | /api/v1/templates |
Get all templates |
| GET | /api/v1/templates/{id} |
Get template by ID |
| GET | /api/v1/templates/name/{name} |
Get template by name |
| PUT | /api/v1/templates/{id} |
Update template |
| DELETE | /api/v1/templates/{id} |
Delete template |
curl -X POST http://localhost:8080/api/v1/notifications \
-H "Content-Type: application/json" \
-d '{
"userId": "550e8400-e29b-41d4-a716-446655440001",
"channel": "EMAIL",
"priority": "HIGH",
"subject": "Welcome!",
"content": "Hello! Welcome to our platform."
}'curl -X POST http://localhost:8080/api/v1/notifications \
-H "Content-Type: application/json" \
-d '{
"userId": "550e8400-e29b-41d4-a716-446655440001",
"channel": "EMAIL",
"templateName": "welcome-email",
"templateVariables": {
"userName": "John"
}
}'curl -X POST http://localhost:8080/api/v1/templates \
-H "Content-Type: application/json" \
-d '{
"name": "order-shipped",
"channel": "EMAIL",
"subjectTemplate": "Your order #{{orderId}} has shipped!",
"bodyTemplate": "Hi {{userName}}, your order is on the way!"
}'-- Core tables
users -- User information
user_preferences -- Per-channel preferences
notification_templates -- Reusable templates
notifications -- Main notification tableKey settings in application.yml:
notification:
rate-limit:
email: 10 # per hour
sms: 5 # per hour
push: 20 # per hour
in-app: 100 # per hour
dedupe:
ttl-seconds: 86400 # 24 hours for event ID tracking
retry:
max-attempts: 3
initial-delay: 60s
multiplier: 5# Run all tests
./mvnw test
# Run with coverage
./mvnw test jacoco:reportSee plan.md for detailed capacity planning including:
- 10M notifications/day capacity
- ~116 notifications/second peak
- Storage and scaling estimates
src/main/java/com/notification/
โโโ config/ # Configuration classes
โโโ controller/ # REST controllers
โโโ dto/ # Request/Response DTOs
โโโ exception/ # Custom exceptions
โโโ kafka/ # Kafka consumer
โโโ model/ # Entity classes
โโโ repository/ # JPA repositories
โโโ scheduler/ # Scheduled jobs
โโโ service/ # Business logic
โโโ channel/ # Channel handlers
- Add authentication (OAuth2/JWT)
- Implement webhooks for delivery status
- Add support for message scheduling
- Implement multi-tenancy
- Add metrics with Prometheus/Grafana
- Support for attachments (email)
- A/B testing for templates
MIT License - feel free to use for your projects!