Getting Started
Overview
Section titled “Overview”This walkthrough installs @serviceconnect/core + @serviceconnect/rabbitmq, defines a typed message, attaches a handler, publishes a message, and shuts the bus down cleanly. By the end you have a working publisher and consumer running against a local RabbitMQ.
Prerequisites
Section titled “Prerequisites”- Node.js 22 LTS or later.
- npm 10+ (bundled with Node; pnpm or yarn work too).
- Docker (for a one-line RabbitMQ).
1. Start RabbitMQ
Section titled “1. Start RabbitMQ”docker run --rm -d --name rabbit -p 5672:5672 -p 15672:15672 rabbitmq:3.13-managementManagement UI: http://localhost:15672 — username guest, password guest.
2. Create a project
Section titled “2. Create a project”mkdir hello-serviceconnect && cd hello-serviceconnectnpm init -ynpm install @serviceconnect/core @serviceconnect/rabbitmqnpm install -D typescript tsx @types/nodeIn package.json set "type": "module". In tsconfig.json use "moduleResolution": "nodenext" and "module": "nodenext".
3. Define a message and a handler
Section titled “3. Define a message and a handler”src/index.ts:
import { createBus, createMessageTypeRegistry, type Message } from '@serviceconnect/core';import { rabbitMQWithRegistry } from '@serviceconnect/rabbitmq';
interface OrderPlaced extends Message { orderId: string; total: number;}
const registry = createMessageTypeRegistry();registry.register<OrderPlaced>('OrderPlaced');
const bus = createBus({ queue: { name: 'hello-serviceconnect' }, transport: rabbitMQWithRegistry( { url: 'amqp://localhost' }, registry, ), registry,});
bus.handle<OrderPlaced>('OrderPlaced', async (msg, ctx) => { console.log('received', msg.orderId, msg.total);});
await bus.start();await bus.publish<OrderPlaced>('OrderPlaced', { correlationId: 'c-1', orderId: 'o-1', total: 19.99,});
await new Promise((r) => setTimeout(r, 500));await bus.stop();4. Run
Section titled “4. Run”node --import tsx src/index.tsExpected output:
received o-1 19.99What just happened?
Section titled “What just happened?”createMessageTypeRegistry()builds a type registry — the bus uses it to map message type strings to TypeScript types at runtime.rabbitMQWithRegistryconstructs a RabbitMQ transport pre-wired with the registry’s polymorphic relationships.createBus(...)returns a bus that owns the consumer, the producer, the pipeline, and the request-reply manager.bus.handle<OrderPlaced>('OrderPlaced', ...)registers a typed handler. The string identifies the message type at runtime; the type parameter gives you compile-time typing of the handler’s payload. The bus throwsMessageTypeNotRegisteredErrorathandle()time if the string was never registered (generics are erased at runtime, so a string/type-parameter disagreement is not — and cannot be — caught).bus.publish<OrderPlaced>('OrderPlaced', payload)publishes a message. The bus serialises the payload, sets headers, and delivers to the exchange.await bus.start()opens connections and begins consumption.await bus.stop()drains in-flight work and closes the transport.
Next steps
Section titled “Next steps”- The Bus — the conceptual tour.
- Messages — type registration and polymorphism.
- Pub/Sub — the canonical event-driven pattern.
- Request/Reply — synchronous-style RPC over the bus.