# Express NATS Microservice

A simple and efficient package for inter-microservice communication using Express.js and NATS Streaming. This package provides a streamlined way to publish and subscribe to messages between microservices, enabling reliable communication in a distributed architecture.

## Features

- **NATS Streaming integration**: Allows microservices to communicate asynchronously.
- **Publish/Subscribe Pattern**: Supports both publishing messages and subscribing to topics.
- **Configurable Acknowledgment**: Provides options for manual acknowledgment, ensuring reliable message delivery.
- **Express.js Compatible**: Easily integrates with Express applications.

## Installation

Install the package using npm:

```bash
npm install express-nats-microservice@1.0.1
```

## Getting Started

### Step 1: Initialize and Configure

To start using the `Express NATS Microservice` package, first create an instance of the `NatsMicroservice` class, specifying the NATS Streaming cluster ID, client ID, and server URL.

```javascript
const NatsMicroservice = require('express-nats-microservice');

const natsService = new NatsMicroservice('test-cluster', 'client-id', 'nats://localhost:4222');
```

### Step 2: Connect to NATS Streaming

Use the `connect` method to establish a connection to the NATS Streaming server. This method returns a Promise, allowing asynchronous handling.

```javascript
natsService.connect()
  .then(() => {
    console.log('Connected to NATS');
  })
  .catch((err) => {
    console.error('Failed to connect:', err);
  });
```

### Step 3: Publish Messages

After connecting, use the `publish` method to send messages to a specific subject. This method takes a subject name and a message object.

```javascript
natsService.publish('order', { event: 'order_created', data: { orderId: 123, userId: 456 } })
  .then((guid) => {
    console.log('Message published with GUID:', guid);
  })
  .catch((err) => {
    console.error('Failed to publish message:', err);
  });
```

### Step 4: Subscribe to Messages

To receive messages, use the `subscribe` method, specifying the subject and a callback function to handle incoming messages. The callback receives parsed JSON data from the message.

```javascript
natsService.subscribe('order', (message) => {
  console.log('Received message:', message);
});
```

### Full Example

Here is a complete example that shows how to connect, publish, and subscribe to messages using the `NatsMicroservice` class.

```javascript
const NatsMicroservice = require('express-nats-microservice');

const natsService = new NatsMicroservice('test-cluster', 'client-id', 'nats://localhost:4222');

async function start() {
  try {
    await natsService.connect();
    console.log('Connected to NATS');

    // Publish a message
    await natsService.publish('order', { event: 'order_created', data: { orderId: 123, userId: 456 } });
    console.log('Message published');

    // Subscribe to messages
    natsService.subscribe('order', (message) => {
      console.log('Received message:', message);
    });

  } catch (error) {
    console.error('Error starting the service:', error);
  }
}

start();
```

## API Documentation

### Class: `NatsMicroservice`

#### Constructor

```javascript
new NatsMicroservice(clusterId, clientId, natsUrl)
```

- `clusterId` (string): The ID of the NATS Streaming cluster.
- `clientId` (string): The unique ID for the client connecting to NATS.
- `natsUrl` (string): The URL of the NATS Streaming server.

#### Methods

- **`connect()`**
  - Connects to the NATS Streaming server.
  - Returns: A `Promise` that resolves when the connection is established.

- **`publish(subject, message)`**
  - Publishes a message to a specific subject.
  - Parameters:
    - `subject` (string): The name of the subject.
    - `message` (object): The message data to be published.
  - Returns: A `Promise` that resolves with the message GUID upon successful publication.

- **`subscribe(subject, onMessage)`**
  - Subscribes to a subject to receive messages.
  - Parameters:
    - `subject` (string): The name of the subject to subscribe to.
    - `onMessage` (function): A callback function that processes incoming messages. Receives a parsed message object as an argument.

## Error Handling

The package includes basic error handling for failed connections, publication errors, and subscription errors. It is recommended to use try-catch blocks or `.catch()` methods to handle potential issues in production environments.

## Requirements

- Node.js version 10 or higher
- NATS Streaming server running and accessible

## Example Use Case

This package is ideal for systems with microservices that need to communicate asynchronously, such as:
- **Order Processing**: One service can publish an "order_created" event, which other services (e.g., inventory, billing) subscribe to and handle in real-time.
- **Notification Systems**: Publish notifications to a message queue for real-time updates to subscribers.

## License

This package is licensed under ISC. See the LICENSE file for more details.