Why amqp-contract?
Define your AMQP contracts once — get type safety, autocompletion, and runtime validation everywhere.
- 🔒 End-to-end type safety — TypeScript knows your message shapes
- 🔄 Reliable retry — Built-in exponential backoff with Dead Letter Queue support
- 📄 AsyncAPI compatible — Generate documentation from your contracts
Quick Example
import { defineContract, defineExchange, defineQueue, definePublisherFirst, defineMessage, } from "@amqp-contract/contract"; import { TypedAmqpClient } from "@amqp-contract/client"; import { TypedAmqpWorker } from "@amqp-contract/worker"; import { z } from "zod"; // 1. Define resources with Dead Letter Exchange for retry support const ordersExchange = defineExchange("orders", "topic", { durable: true }); const ordersDlx = defineExchange("orders-dlx", "topic", { durable: true }); const orderProcessingQueue = defineQueue("order-processing", { durable: true, deadLetter: { exchange: ordersDlx, routingKey: "order.failed" }, }); // 2. Define message with schema validation const orderMessage = defineMessage( z.object({ orderId: z.string(), amount: z.number(), }), ); // 3. Publisher-first pattern ensures consistency const { publisher: orderCreatedPublisher, createConsumer: createOrderCreatedConsumer } = definePublisherFirst(ordersExchange, orderMessage, { routingKey: "order.created" }); // 4. Create consumer from event const { consumer: processOrderConsumer, binding: orderBinding } = createOrderCreatedConsumer(orderProcessingQueue); // 5. Define contract const contract = defineContract({ exchanges: { orders: ordersExchange, ordersDlx }, queues: { orderProcessing: orderProcessingQueue }, bindings: { orderBinding }, publishers: { orderCreated: orderCreatedPublisher }, consumers: { processOrder: processOrderConsumer }, }); // 6. Type-safe publishing with validation const client = await TypedAmqpClient.create({ contract, urls: ["amqp://localhost"], }).resultToPromise(); await client.publish("orderCreated", { orderId: "ORD-123", // ✅ TypeScript knows! amount: 99.99, }); // 7. Type-safe consuming with reliable retry const worker = await TypedAmqpWorker.create({ contract, handlers: { processOrder: async (message) => { console.log(message.orderId); // ✅ TypeScript knows! }, }, urls: ["amqp://localhost"], retry: { maxRetries: 3, initialDelayMs: 1000 }, }).resultToPromise();
Installation
pnpm add @amqp-contract/contract @amqp-contract/client @amqp-contract/worker
Documentation
- Get Started — Get running in 5 minutes
- Core Concepts — Understand the fundamentals
- NestJS Integration — First-class NestJS support
- Examples — Real-world usage patterns
Packages
| Package | Description |
|---|---|
| @amqp-contract/contract | Contract builder and type definitions |
| @amqp-contract/client | Type-safe client for publishing |
| @amqp-contract/worker | Type-safe worker with retry support |
| @amqp-contract/client-nestjs | NestJS client integration |
| @amqp-contract/worker-nestjs | NestJS worker integration |
| @amqp-contract/asyncapi | AsyncAPI 3.0 generator |
Contributing
See CONTRIBUTING.md.
License
MIT