A complete event-driven application built with Apache Kafka and Node.js, demonstrating producer-consumer patterns, event schemas, error handling, and scalability through consumer groups.
This application consists of:
- Kafka Infrastructure: Zookeeper, Kafka broker, and Kafka UI (via Docker Compose)
- Producer Service: Publishes events to Kafka topics
- Consumer Services: Multiple consumers processing events from different topics
- Event Schemas: Structured event definitions for orders and users
- Configuration: Centralized configuration for Kafka and application settings
- Docker and Docker Compose installed
- Node.js (v16 or higher)
- npm or yarn
# Start Zookeeper, Kafka, and Kafka UI
docker-compose up -d
# Verify services are running
docker-compose psThe following services will be available:
- Kafka Broker:
localhost:9092 - Kafka UI:
http://localhost:8080 - Zookeeper:
localhost:2181
npm installThe .env file is already configured with default values. Modify if needed:
KAFKA_BROKERS=localhost:9092
CONSUMER_GROUP_ID=event-consumer-group
TOPIC_ORDERS=orders
TOPIC_USERS=users
TOPIC_NOTIFICATIONS=notificationsTerminal 1 - Start Consumer API:
npm run start:consumer-api
# Consumer API will run on http://localhost:3001Terminal 2 - Start Producer API:
npm run start:producer-api
# Producer API will run on http://localhost:3000Terminal 3 - Use Postman or curl to interact:
# Health check
curl http://localhost:3000/health
curl http://localhost:3001/health
# Publish an order event
curl -X POST http://localhost:3000/api/events/orders \
-H "Content-Type: application/json" \
-d '{
"userId": "user-123",
"items": [{"productId": "prod-1", "quantity": 2, "price": 29.99}],
"totalAmount": 59.98,
"shippingAddress": {
"street": "123 Main St",
"city": "San Francisco",
"state": "CA",
"zipCode": "94102"
}
}'
# Get consumer statistics
curl http://localhost:3001/api/statsTerminal 1 - Start Consumer:
# Multi-topic consumer (listens to all topics)
npm run consumer
# Or run specific consumers
npm run consumer:orders
npm run consumer:usersTerminal 2 - Run Producer:
# Run the producer with sample events
npm run producer
# Or run test producer to generate multiple events
npm run test:producer# Terminal 1 - Consumer API with auto-reload
npm run dev:consumer-api
# Terminal 2 - Producer API with auto-reload
npm run dev:producer-api
# Or for CLI mode:
npm run dev:consumer
npm run dev:producer- GET
/health- Check producer service health
-
POST
/api/events/orders- Publish order events- Required fields:
userId,items,totalAmount - Optional:
shippingAddress,eventType
- Required fields:
-
POST
/api/events/users- Publish user events- Required fields:
email,firstName,lastName - Optional:
phoneNumber,preferences,eventType
- Required fields:
-
POST
/api/events/notifications- Publish notification events- Required fields:
type,recipient - Optional:
message,metadata
- Required fields:
-
POST
/api/events/payments- Publish payment events- Required fields:
orderId,amount,paymentMethod - Optional:
status,transactionId
- Required fields:
-
POST
/api/events/batch- Publish multiple events at once- Body:
{ "events": [{ "type": "order|user|notification|payment", "data": {...} }] }
- Body:
- GET
/health- Check consumer service health
-
GET
/api/stats- Get consumer statistics- Returns: messages processed, errors, uptime, messages by topic
-
GET
/api/consumer-groups- Get consumer group information- Returns: group ID, subscribed topics, status
- POST
/api/consumer/pause- Pause message consumption - POST
/api/consumer/resume- Resume message consumption - POST
/api/stats/reset- Reset statistics counters
.
βββ docker-compose.yml # Kafka infrastructure setup
βββ package.json # Dependencies and scripts
βββ .env # Environment configuration
βββ config/
β βββ kafka.config.js # Kafka configuration
β βββ logger.js # Winston logger setup
βββ schemas/
β βββ orderSchema.js # Order event schema
β βββ userSchema.js # User event schema
βββ producer/
β βββ kafkaProducer.js # Base Kafka producer class
β βββ index.js # Event producer with business logic
β βββ testProducer.js # Test event generator
βββ consumer/
β βββ kafkaConsumer.js # Base Kafka consumer class
β βββ index.js # Multi-topic consumer
β βββ orderConsumer.js # Order-specific consumer
β βββ userConsumer.js # User-specific consumer
βββ logs/ # Application logs (auto-generated)
The producer service supports:
- Structured Events: Type-safe event schemas with validation
- Multiple Topics: Orders, users, notifications, and payments
- Batch Publishing: Send multiple events in a single request
- Retry Logic: Automatic retry with exponential backoff
- Message Keys: Partition events by key for ordering guarantees
The consumer service provides:
- Consumer Groups: Multiple consumers for horizontal scaling
- Topic Subscription: Subscribe to single or multiple topics
- Error Handling: Graceful error handling with logging
- Offset Management: Automatic and manual offset commits
- Pause/Resume: Control consumer flow dynamically
{
eventId: "uuid",
eventType: "ORDER_CREATED | ORDER_UPDATED | ORDER_CANCELLED",
timestamp: "ISO-8601",
orderId: "uuid",
userId: "string",
items: [{ productId, quantity, price }],
totalAmount: number,
currency: "USD",
status: "PENDING | PROCESSING | COMPLETED",
shippingAddress: { street, city, state, zipCode }
}{
eventId: "uuid",
eventType: "USER_CREATED | USER_UPDATED | USER_DELETED",
timestamp: "ISO-8601",
userId: "uuid",
email: "string",
firstName: "string",
lastName: "string",
phoneNumber: "string",
preferences: {}
}Edit config/kafka.config.js to customize:
- Broker addresses
- Connection timeouts
- Retry policies
- Consumer group settings
Default topics are configured in .env:
orders- Order-related eventsusers- User-related eventsnotifications- Notification eventspayments- Payment events
Access the Kafka UI at http://localhost:8080 to:
- View topics and partitions
- Monitor consumer groups
- Inspect messages
- Check broker health
Application logs are stored in the logs/ directory:
combined.log- All log levelserror.log- Error logs only
Console logs are enabled in development mode.
npm run test:producerThis will generate:
- 5 order events
- 3 user events
- 3 notification events
- Start a consumer:
npm run consumer - Run the test producer:
npm run test:producer - Check logs to verify events are processed
- View events in Kafka UI at
http://localhost:8080
To demonstrate horizontal scaling, run multiple consumer instances:
# Terminal 1
npm run consumer:orders
# Terminal 2
npm run consumer:orders
# Terminal 3
npm run consumer:ordersKafka will automatically distribute partitions among consumers in the same group.
order-consumer-group- Order processing consumersuser-consumer-group- User processing consumersmulti-topic-consumer-group- Multi-topic consumers
const EventProducer = require('./producer');
const producer = new EventProducer();
await producer.initialize();
await producer.publishOrderEvent({
userId: 'user-123',
items: [{ productId: 'prod-1', quantity: 2, price: 29.99 }],
totalAmount: 59.98
});
await producer.shutdown();const KafkaConsumer = require('./consumer/kafkaConsumer');
const consumer = new KafkaConsumer('my-consumer-group');
await consumer.connect();
await consumer.subscribe('my-topic');
consumer.registerHandler('my-topic', async (message) => {
console.log('Received:', message.value);
});
await consumer.run();# Check if Kafka is running
docker-compose ps
# View Kafka logs
docker-compose logs kafka
# Restart Kafka services
docker-compose restart- Verify consumer is subscribed to the correct topic
- Check consumer group ID is unique or shared appropriately
- Ensure messages are being produced (check Kafka UI)
- Verify offset position (may need to reset to beginning)
If ports 9092, 2181, or 8080 are in use:
- Stop conflicting services
- Or modify ports in
docker-compose.yml
# Stop Kafka infrastructure
docker-compose down
# Remove volumes (deletes all data)
docker-compose down -vrm -rf logs/Feel free to submit issues and enhancement requests!
MIT License - feel free to use this project for learning and development.
Happy Event Streaming! π