npm package: @heavybit/queue-publisher-package
Description: Shared queue publisher package that allows microservices to publish to Rabbit MQ queues
Author: Nicholas Kute
Latest version: 1.0.5

# Introduction

The RabbitMQPublisher package is a lightweight Node.js library designed to simplify message publishing to RabbitMQ queues. This package abstracts the complexities of establishing a RabbitMQ connection, creating channels, and managing queues, allowing developers to integrate RabbitMQ into their microservices with minimal effort.

# Features
- Persistent RabbitMQ connection management.
- Automatic queue declaration and durable message publishing.
- Graceful handling of connection and channel closure.
- Built-in error handling for connection and message publishing.
- Simple integration into Node.js microservices.

# Technologies Used
- **Node.js**: The core runtime environment for building the package.
- **RabbitMQ**: A message broker for sending messages between microservices.
- **amqplib**: A Node.js library for working with RabbitMQ.

# Installation
You can install the package via npm by running the following command:

`npm install @heavybit/queue-publisher-package`

# Requirements
- Node.js version 12 or higher.
- RabbitMQ installed locally or accessible via a cloud instance.


# Usage
Here’s how to integrate the RabbitMQPublisher package into your project:

1. Import the Package
First, import the RabbitMQPublisher class into your Node.js application:

`const RabbitMQPublisher = require('@heavybit/queue-publisher-package');`

2. Initialize the Publisher
Create an instance of the RabbitMQPublisher:

`const publisher = new RabbitMQPublisher();`

3. Publish Messages to a Queue
You can easily publish messages using the publishToQueue() method. The method handles establishing a connection, asserting the queue, and sending the message.

```
const queueName = 'taskQueue';
const message = { task: 'Process Order', orderId: 12345 };

(async () => {
  try {
    await publisher.publishToQueue(queueName, message);
    console.log('Message sent successfully');
  } catch (error) {
    console.error('Failed to send message:', error);
  } finally {
    await publisher.close(); // Gracefully close the connection
  }
})();
``` 

4. Close the Connection
Always ensure to close the connection and channel once you are done publishing messages:

```
(async () => {
  try {
    await publisher.close();
    console.log('RabbitMQ connection closed');
  } catch (error) {
    console.error('Failed to close connection:', error);
  }
})();
```

# Methods
`async connect(rabbitMQUrl)`

Establishes a connection to RabbitMQ and creates a channel. By default, the package uses the RABBITMQ_URL environment variable or defaults to amqp://rabbitmq.

```
await publisher.connect('amqp://custom-url');
```

`async publishToQueue(queue, message)`

Ensures that the RabbitMQ connection is established and the specified queue is asserted, before sending the message as a persistent JSON message.

```
await publisher.publishToQueue('myQueue', { key: 'value' });
```

`async close()`

Closes both the RabbitMQ channel and connection gracefully.

```
await publisher.close();
```

# Environment Configuration
By default, the package uses the following environment variable to configure the RabbitMQ connection:

RABBITMQ_URL: The RabbitMQ URL, which defaults to amqp://rabbitmq if not set.

Example .env configuration:

```
RABBITMQ_URL=amqp://your-rabbitmq-url
```

# Error Handling
The package includes robust error handling mechanisms:

If a connection to RabbitMQ fails, an error is thrown and logged.
If message publishing fails, the error is caught, logged, and rethrown.
The close() method gracefully handles errors during the closure of RabbitMQ connections and channels.

Example:

```
(async () => {
  try {
    await publisher.publishToQueue('queue', { message: 'Hello World' });
  } catch (error) {
    console.error('Error:', error.message);
  }
})();
```

# Example: Integrating into a Microservice
Here’s an example of how you can integrate the RabbitMQPublisher into an Express-based microservice to publish messages to a queue:

```
const express = require('express');
const RabbitMQPublisher = require('@heavybit/queue-publisher-package');

const app = express();
const publisher = new RabbitMQPublisher();

// Middleware to parse JSON bodies
app.use(express.json());

app.post('/publish', async (req, res) => {
  const { queue, message } = req.body;

  try {
    await publisher.publishToQueue(queue, message);
    res.status(200).send('Message sent to RabbitMQ');
  } catch (error) {
    console.error('Failed to send message:', error);
    res.status(500).send('Failed to send message');
  }
});

app.listen(3000, () => {
  console.log('Microservice is running on port 3000');
});
```