UNPKG

rapid-mq

Version:

A simple and fast RabbitMQ client for Node.js

369 lines (281 loc) 8.91 kB
<p align="center"> <img src="assets/logo-with-text.png" alt="Rapid-MQ Logo" width="320"/> </p> # Rapid-MQ **Rapid-MQ** is a simple, fast, and flexible Node.js library for integrating with RabbitMQ. It provides easy-to-use abstractions for Pub/Sub, RPC, and Direct messaging patterns, making it effortless to build scalable distributed systems. --- ## Features - 🚀 **Easy Integration**: Minimal setup, works out-of-the-box. - 📨 **Pub/Sub, RPC, Direct**: Unified API for common messaging patterns. - 🛡️ **TypeScript Support**: Fully typed for safer code. - **Fast & Lightweight**: No unnecessary dependencies. --- ## Installation ```bash npm install rapid-mq ``` --- ## Quick Start Examples ### 1. Publisher/Subscriber Pattern Use `PubSubMessager` for broadcast-style messaging where multiple consumers can receive the same message. **Publisher Example (with TTL):** ```typescript import { RapidConnector, PubSubMessager } from 'rapid-mq'; async function main() { const connector = new RapidConnector({ url: 'amqp://localhost', appId: 'publisher-service' }); await connector.connect(); const pubsub = new PubSubMessager({ connector, appGroup: 'notifications', // Logical grouping exchangeName: 'events' // Optional custom exchange }); await pubsub.initialize(); await pubsub.publish('user.created', { userId: '123', email: 'user@example.com', 10000 // (Optional) Publish with TTL (e.g., 10 seconds) }); } main(); ``` **Subscriber Example:** ```typescript import { RapidConnector, PubSubMessager } from 'rapid-mq'; async function main() { const connector = new RapidConnector({ url: 'amqp://localhost', appId: 'email-service' }); await connector.connect(); const pubsub = new PubSubMessager({ connector, appGroup: 'notifications' }); await pubsub.initialize(); await pubsub.subscribe('user.created', (message) => { console.log('New user:', message); }); } main(); ``` --- ### 2. RPC (Remote Procedure Call) Pattern Use `RpcMessager` for request-response style communication. **Server Example:** ```typescript import { RapidConnector, RpcMessager } from 'rapid-mq'; async function main() { const connector = new RapidConnector({ url: 'amqp://localhost', appId: 'math-service' }); await connector.connect(); const rpc = new RpcMessager({ connector, exchangeName: 'math', // Optional timeoutInSec: 30 // Default: 5 seconds }); await rpc.initialize(); await rpc.server('add', async (a: number, b: number) => { return a + b; }); } main(); ``` **Client Example:** ```typescript import { RapidConnector, RpcMessager } from 'rapid-mq'; async function main() { const connector = new RapidConnector({ url: 'amqp://localhost', appId: 'calculator-app' }); await connector.connect(); const rpc = new RpcMessager({ connector }); await rpc.initialize(); const result = await rpc.call<number>('add', 5, 3); console.log('5 + 3 =', result); // Output: 8 } main(); ``` --- ### 3. Direct Messaging Pattern Use `DirectMessager` for point-to-point communication where each message should be processed by exactly one consumer. **Sender Example:** ```typescript import { RapidConnector, DirectMessager } from 'rapid-mq'; async function main() { const connector = new RapidConnector({ url: 'amqp://localhost', appId: 'order-service' }); await connector.connect(); const direct = new DirectMessager({ connector, consumerTag: 'order-service-1', exchangeName: 'orders' // Optional }); await direct.initialize(); await direct.send('payment-service', { orderId: '12345', amount: 99.99 }); } main(); ``` **Receiver Example:** ```typescript import { RapidConnector, DirectMessager } from 'rapid-mq'; async function main() { const connector = new RapidConnector({ url: 'amqp://localhost', appId: 'payment-service' }); await connector.connect(); const direct = new DirectMessager({ connector, consumerTag: 'payment-service' }); await direct.initialize(); await direct.listen((message) => { console.log('Processing payment:', message); }); } main(); ``` --- ## API Reference ### RapidConnector Manages the connection to RabbitMQ. **Constructor:** ```typescript new RapidConnector(options: { url: string; appId: string; encoder?: RapidEncoder; // Optional custom encoder }) ``` **Properties:** - `url: string` - RabbitMQ connection URL. - `appId: string` - Unique identifier for your application. - `connected: boolean` - Current connection status. - `encoder: RapidEncoder` - Encoder used for message serialization. **Methods:** - `connect(): Promise<void>` - Establish connection to RabbitMQ. - `disconnect(): Promise<void>` - Close connection gracefully. - `connection` (getter) - Returns the underlying amqplib connection. --- ### PubSubMessager Implements the publish/subscribe messaging pattern. **Constructor:** ```typescript new PubSubMessager(options: { connector: RapidConnector; appGroup: string; exchangeName?: string; durable?: boolean; exclusive?: boolean; }) ``` **Properties:** - `connector: RapidConnector` - Connection instance. - `appGroup: string` - Logical group name for consumers. - `exchangeName: string` - Exchange name (default: 'pubsub-exchange'). - `durable: boolean` - Whether the exchange/queue is durable (default: true). - `exclusive: boolean` - Whether the queue is exclusive (default: false). **Methods:** - `initialize(): Promise<void>` - Set up exchanges and queues. - `publish(topic: string, message: any): Promise<boolean>` - Publish message to topic. - `subscribe(topic: string, callback: (msg: any) => void): Promise<void>` - Subscribe to topic. --- ### RpcMessager Implements the request/response (RPC) messaging pattern. **Constructor:** ```typescript new RpcMessager(options: { connector: RapidConnector; exchangeName?: string; timeoutInSec?: number; durable?: boolean; exclusive?: boolean; emitter?: EventEmitter; }) ``` **Properties:** - `connector: RapidConnector` - Connection instance. - `exchangeName: string` - Exchange name (default: 'rpc-exchange'). - `timeoutInSec: number` - RPC timeout in seconds (default: 5). - `durable: boolean` - Whether the exchange/queue is durable (default: true). - `exclusive: boolean` - Whether the queue is exclusive (default: false). **Methods:** - `initialize(): Promise<void>` - Set up RPC infrastructure. - `call<T>(method: string, ...args: any[]): Promise<T>` - Call remote method. - `server(method: string, handler: Function): Promise<void>` - Register RPC handler. --- ### DirectMessager Implements point-to-point (direct) messaging. **Constructor:** ```typescript new DirectMessager(options: { connector: RapidConnector; consumerTag: string; exchangeName?: string; durable?: boolean; exclusive?: boolean; }) ``` **Properties:** - `connector: RapidConnector` - Connection instance. - `consumerTag: string` - Unique identifier for consumer. - `exchangeName: string` - Exchange name (default: 'direct-exchange'). - `durable: boolean` - Whether the exchange/queue is durable (default: true). - `exclusive: boolean` - Whether the queue is exclusive (default: false). **Methods:** - `initialize(): Promise<void>` - Set up direct exchange and queue. - `send(to: string, message: any): Promise<boolean>` - Send message to specific consumer. - `listen(callback: (msg: any) => void): Promise<void>` - Listen for messages. --- ## Encoder System Rapid-MQ uses an encoder system to serialize and deserialize messages. By default, it uses JSON, but you can provide your own encoder by implementing the `RapidEncoder` interface. **Default Encoder:** - Encodes messages as `[type, value]` JSON arrays. - Handles special types like `Date`. **Custom Encoder Example:** ```typescript import { RapidEncoder } from 'rapid-mq'; class MyEncoder implements RapidEncoder { async encode(message: unknown): Promise<Buffer> { // Custom serialization logic return Buffer.from(JSON.stringify(message)); } async decode(data: Buffer): Promise<unknown> { // Custom deserialization logic return JSON.parse(data.toString()); } } const connector = new RapidConnector({ url: 'amqp://localhost', appId: 'my-app', encoder: new MyEncoder() }); ``` **RapidEncoder Interface:** ```typescript interface RapidEncoder { encode(message: unknown, exchange: string, topic: string): Promise<Buffer>; decode(data: Buffer, exchange: string, topic: string): Promise<unknown>; } ``` --- ## Best Practices - **Always call `initialize()`** on messager instances before using them. - **Handle errors** in your callbacks and publishing logic. - **Disconnect** your connector when your app shuts down. --- ## License ISC © vasu_gajjar <p align="center"> <img src="assets/logo.png" alt="Rapid-MQ Logo" width="64"/>