An open API service indexing awesome lists of open source software.

https://github.com/boringnode/bus

A simple and lean service bus implementation for Node.js
https://github.com/boringnode/bus

bus framework-agnostic nodejs

Last synced: 4 days ago
JSON representation

A simple and lean service bus implementation for Node.js

Awesome Lists containing this project

README

          


@boringnode/bus

[![typescript-image]][typescript-url]
[![gh-workflow-image]][gh-workflow-url]
[![npm-image]][npm-url]
[![npm-download-image]][npm-download-url]
[![license-image]][license-url]


`@boringnode/bus` is a service bus implementation for Node.js. It is designed to be simple and easy to use.

Currently, it supports the following transports:


👉 Memory: A simple in-memory transport for testing purposes.

👉 Redis: A Redis transport for production usage.

👉 Mqtt: A Mqtt transport for production usage.

## Table of Contents

- [Installation](#installation)
- [Usage](#usage)
- [Retry Queue](#retry-queue)

## Installation

```bash
npm install @boringnode/bus
```

## Usage

The module exposes a manager that can be used to register buses.

```typescript
import { BusManager } from '@boringnode/bus'
import { redis } from '@boringnode/bus/transports/redis'
import { mqtt } from '@boringnode/bus/transports/mqtt'
import { memory } from '@boringnode/bus/transports/memory'

const manager = new BusManager({
default: 'main',
transports: {
main: {
transport: memory(),
},
redis: {
transport: redis({
host: 'localhost',
port: 6379,
}),
},
mqtt: {
transport: mqtt({
host: 'localhost',
port: 1883,
}),
},
}
})
```

Once the manager is created, you can subscribe to channels and publish messages.

```typescript
manager.subscribe('channel', (message) => {
console.log('Received message', message)
})

manager.publish('channel', 'Hello world')
```

By default, the bus will use the `default` transport. You can specify different transport by using the `use` method.

```typescript
manager.use('redis').publish('channel', 'Hello world')
manager.use('mqtt').publish('channel', 'Hello world')
```

### Without the manager

If you don't need multiple buses, you can create a single bus directly by importing the transports and the Bus class.

```typescript
import { Bus } from '@boringnode/bus'
import { RedisTransport } from '@boringnode/bus/transports/redis'

const transport = new RedisTransport({
host: 'localhost',
port: 6379,
})

const bus = new Bus(transport, {
retryQueue: {
retryInterval: '100ms'
}
})
```

## Retry Queue

The bus also supports a retry queue. When a message fails to be published, it will be moved to the retry queue.

For example, your Redis server is down.

```typescript
const manager = new BusManager({
default: 'main',
transports: {
main: {
transport: redis({
host: 'localhost',
port: 6379,
}),
retryQueue: {
retryInterval: '100ms'
}
},
}
})

manager.use('redis').publish('channel', 'Hello World')
```

The message will be moved to the retry queue and will be retried every 100ms.

You have multiple options to configure the retry queue.

```typescript
export interface RetryQueueOptions {
// Enable the retry queue (default: true)
enabled?: boolean

// Defines if we allow duplicates messages in the retry queue (default: true)
removeDuplicates?: boolean

// The maximum size of the retry queue (default: null)
maxSize?: number | null

// The interval between each retry (default: false)
retryInterval?: Duration | false
}
```

## Test helpers

The module also provides some test helpers to make it easier to test the code that relies on the bus. First, you can use the `MemoryTransport` to create a bus that uses an in-memory transport.

You can also use the `ChaosTransport` to simulate a transport that fails randomly, in order to test the resilience of your code.

```ts
import { Bus } from '@boringnode/bus'
import { ChaosTransport } from '@boringnode/bus/test_helpers'

const buggyTransport = new ChaosTransport(new MemoryTransport())
const bus = new Bus(buggyTransport)

/**
* Now, every time you will try to publish a message, the transport
* will throw an error.
*/
buggyTransport.alwaysThrow()
```

[gh-workflow-image]: https://img.shields.io/github/actions/workflow/status/boringnode/bus/checks.yml?branch=0.x&style=for-the-badge
[gh-workflow-url]: https://github.com/boringnode/bus/actions/workflows/checks.yml
[npm-image]: https://img.shields.io/npm/v/@boringnode/bus.svg?style=for-the-badge&logo=npm
[npm-url]: https://www.npmjs.com/package/@boringnode/bus
[npm-download-image]: https://img.shields.io/npm/dm/@boringnode/bus?style=for-the-badge
[npm-download-url]: https://www.npmjs.com/package/@boringnode/bus
[typescript-image]: https://img.shields.io/badge/Typescript-294E80.svg?style=for-the-badge&logo=typescript
[typescript-url]: https://www.typescriptlang.org
[license-image]: https://img.shields.io/npm/l/@boringnode/bus?color=blueviolet&style=for-the-badge
[license-url]: LICENSE.md