A complete event-driven microservice demonstrating how nats-plus integrates with the core-ts ecosystem.
This project shows how to build a lightweight message-driven service that:
- Publishes events to NATS
- Consumes events from NATS
- Validates incoming messages
- Retries failed processing
- Persists data to MySQL
- Exposes Kubernetes-ready health checks
Rather than demonstrating nats-plus in isolation, this sample shows how multiple libraries work together to build a production-style application.
HTTP Request
│
POST /send (JSON)
│
▼
nats-plus Publisher
│
▼
NATS Server
│
▼
nats-plus Subscriber
│
▼
validation-core
│
▼
message-processing
(Retry / Error Handler)
│
▼
mysql2-core Writer
│
▼
MySQL
GET /health
│
▼
health-service
│
┌─────────┴─────────┐
▼ ▼
NATSChecker MySQLChecker
- Event-driven architecture
- Type-safe publisher and subscriber
- Automatic JSON serialization
- Queue group support
- Message validation
- Configurable retry policy
- MySQL persistence
- Health checks
- Structured logging
- Environment-based configuration
| Library | Purpose |
|---|---|
| nats-plus | Publish and subscribe to NATS |
| mysql2-core | Write data into MySQL |
| validation-core | Validate incoming messages |
| message-processing | Retry and error handling |
| health-service | Health endpoint |
| logger-core | Structured logging |
| config-plus | Configuration management |
src
├── app.ts
├── config.ts
└── user
└── index.ts
- app.ts – application bootstrap
- config.ts – application configuration
- user/ – domain model and validation schema
HTTP POST
│
▼
Publisher.publish()
│
▼
NATS
│
▼
Subscriber.subscribe()
│
▼
Validator
│
▼
Retry Processor
│
▼
MySQL Writer
- Node.js 18+
- NATS Server
- MySQL 8+
npm installExample using Docker:
docker run --rm -p 4222:4222 natsCreate a database.
CREATE DATABASE masterdata;Create the table.
CREATE TABLE users (
id VARCHAR(40) PRIMARY KEY,
username VARCHAR(255) NOT NULL,
email VARCHAR(120),
phone VARCHAR(14),
date_of_birth DATETIME
);Update src/config.ts if necessary.
Development
npm run devor
npm startProduction
npm run build
npm run prodPOST /send
Example
{
"id": "1001",
"username": "john",
"email": "john@example.com",
"phone": "0123456789",
"dateOfBirth": "1990-01-01T00:00:00Z"
}The request flow is:
HTTP
↓
Publisher
↓
NATS
↓
Subscriber
↓
Validation
↓
Retry
↓
MySQL
GET /health
The endpoint checks:
- NATS connectivity
- MySQL connectivity
Example response
{
"status": "UP"
}Incoming messages are validated using validation-core.
The sample validates:
- Required fields
- Email format
- Phone format
- Maximum lengths
- Date type
Invalid messages are rejected before reaching the database.
Failed writes are retried according to the configured retry policy.
Example configuration:
retries: {
1: 10000,
2: 15000,
3: 25000
}Meaning:
- First retry after 10 seconds
- Second retry after 15 seconds
- Third retry after 25 seconds
The subscriber joins the queue group:
"user-service"This allows multiple instances of the service to run concurrently while ensuring each message is processed by only one instance.
Application configuration is located in:
src/config.ts
Configuration includes:
- HTTP server
- MySQL
- NATS
- Retry policy
- Logging
config-plus merges:
- Default configuration
- Environment variables
- Environment-specific configuration
The sample intentionally keeps each component focused on a single responsibility.
Publisher
│
▼
Subscriber
│
▼
Validator
│
▼
Retry Processor
│
▼
Writer
This separation makes every component reusable and independently testable.
This sample demonstrates how the core-ts ecosystem works together.
Application
│
┌────────────────┼────────────────┐
▼ ▼ ▼
logger-core config-plus health-service
│
▼
nats-plus
│
▼
validation-core
│
▼
message-processing
│
▼
mysql2-core
│
▼
MySQL
This sample demonstrates:
- Event-driven architecture
- Type-safe messaging
- Message validation
- Retry processing
- Persistence
- Health monitoring
- Dependency injection
- Composition of reusable libraries
MIT