Skip to content

Repository files navigation

nats-sample

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.


Architecture

                        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

Features

  • 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

Ecosystem Integration

This sample demonstrates how several core-ts libraries work together.

Library Purpose
nats-plus Publish and subscribe to NATS
message-processing Retry and error handling
mysql2-core Write data into MySQL
validation-core Validate incoming messages
health-service Health endpoint
logger-core Structured logging
config-plus Configuration management

Each library focuses on a single responsibility.

That demonstrates the intended layering very well.


Project Structure

src
├── app.ts
├── config.ts
└── user
    └── index.ts
  • app.ts – application bootstrap
  • config.ts – application configuration
  • user/ – domain model and validation schema

Processing Flow

     HTTP POST
         │
         ▼
 Publisher.publish()
         │
         ▼
        NATS
         │
         ▼
Subscriber.subscribe()
         │
         ▼
     Validator
         │
         ▼
   Retry Processor
         │
         ▼
    MySQL Writer

Getting Started

Prerequisites

  • Node.js 18+
  • NATS Server
  • MySQL 8+

Install

npm install

Start NATS

Example using Docker:

docker run --rm -p 4222:4222 nats

Configure MySQL

Create 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.


Running

Development

npm run dev

or

npm start

Production

npm run build
npm run prod

Sending a Message

POST /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

Health Check

GET /health

The endpoint checks:

  • NATS connectivity
  • MySQL connectivity

They can easily be extended to include additional infrastructure services.

Example response

{
  "status": "UP",
  "details": {
    "nats": {
      "status": "UP"
    },
    "mysql": {
      "status": "UP"
    }
  }
}

Validation

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.

    NATS

      ↓

  Processor

      ↓

  Validator

      ↓

Business Logic

Retry

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

Queue Groups

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.


Configuration

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

Design

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.


Ecosystem

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

Learning Objectives

This sample demonstrates:

  • Event-driven architecture
  • Type-safe messaging
  • Message validation
  • Retry processing
  • Persistence
  • Health monitoring
  • Dependency injection
  • Composition of reusable libraries

Separation of Responsibilities

One of the goals of this sample is to demonstrate proper layering.

nat-plus

Responsible for:

  • Producer
  • Consumer
  • Header mapping
  • Health checking

message-processing

Responsible for:

  • JSON deserialization
  • Validation
  • Processing pipeline
  • Retry
  • Error handling
  • Logging

Business Layer

Responsible only for business logic.

Process Order

Save Customer

Import Product

Send Notification

Business services remain independent of NATS.


Why This Architecture?

Instead of embedding business logic inside RabbitMQ consumers,

  Consumer

      ↓

Business Logic

      ↓

   Database

      ↓

    Retry

      ↓

  Validation

the sample separates every concern.

  Consumer

      ↓

  Processor

      ↓

  Validation

      ↓

    Retry

      ↓

Business Logic

      ↓

    Writer

Each layer has a single responsibility.

This makes the application:

  • easier to maintain
  • easier to test
  • easier to replace infrastructure
  • easier to extend

Production Considerations

This sample demonstrates production-oriented practices including:

  • Layered architecture
  • Strong typing
  • Validation
  • Retry processing
  • Logging
  • Health monitoring
  • Infrastructure abstraction

Additional production features such as dead-letter queues, delayed retry queues, metrics, and distributed tracing can be added without changing the application architecture.


License

MIT

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages