Easy to use
Simple, pragmatic, super lightweight, no magic, just what you need and all Open Source.
Easy to use
Simple, pragmatic, super lightweight, no magic, just what you need and all Open Source.
Agnostic
You can use it with any framework or library, wether you’re fully backend or backend for frontend, we got you covered.
Middlewares
Envelopes and Stamps
Handle cross-cutting concerns with Envelopes and Stamps.
Type-safe
Define your query
, command
or event
. The bus
instance is fully typed. (You’ll have auto-completion for free!)
Install it
pnpm add missive.js
npm install missive.js
yarn add missive.js
Define your handler for query
, command
or event
// the Types to use in the bus configurationtype Command = { email: string };type Result = Awaited<ReturnType<typeof handler>>;export type Definition = CommandHandlerDefinition<'createUser', Command, Result>;
// the handler to handle the intentconst handler = async (envelope: Envelope<Command>, deps: Deps) => { const { email } = envelope.message; await deps.mailer('subject', email, 'plop', { html: 'html', text: 'text' }); return { success: true };};
// the factory to create the handler with the dependencies you may needexport const Factory = (deps: Deps) => (query: Envelope<Command>) => handler(query, deps);
Create a bus
instance with all your definitions
type CommandHandlerRegistry = SendRegistrationEmailDefinition & SendNotificationDefinition;const bus = createCommandBus<CommandHandlerRegistry>();
bus.register('sendRegistrationEmail', Factory({ mailer }));
Dispatch an intent
const intent = bus.createCommand('sendRegistrationEmail', { email: 'plopix@example.com' });// ...const { envelope, result } = await bus.dispatch(intent);
Without Middlewares, a Service Bus is almost useless, we provide built-in middlewares that you can use out of the box. They are all optional and you can use them all together or just the ones you need. Middlewares provides a way to handle cross-cutting concerns. They are key to keep your code clean and maintainable. And most of all, they are easy to write and to use, and they can be generic!
That’s the power of Missive.js! Here are the built-in middlewares:
Validator Middleware
Validate the intent before it’s handled, and the result after it’s handled.
Read the docLogger Middleware
Easily add observability to your application by logging the messages (intent) and the full Envelope (with the Stamps) before and once handled (or errored) in the backend of your choice.
Read the docCaching Middleware
Caches results for faster access in future queries, reducing load and making it blazing fast with built-in Stale While Revalidating pattern.
Read the docRetry Middleware
Automatically retries processing an intent a specified number of times before considering it as failed, with different backoff strategy.
Read the docWebhook Middleware
The Webhook Middleware is going to send the envelope(s) to confirured webhook(s) (post processing). It’s another powerful way to decouple your system and to make it more resilient or to simply add Observability!.
Read the docLock Middleware
It provide a way to lock the processing of a message based on something in the intent itself. For instance your could lock the command
that touches a Cart.
Feature Flag Middleware
This middleware ensures that requests are conditionally processed based on the state of feature flags, enabling dynamic feature management, safer rollouts, and efficient A/B testing.
Read the docMock Middleware
This middleware is pretty useful in development mode, to mock the result of a specific intent to bypass the handler.
Read the docAsync Middleware
You can already do async if you don’t await in your handler, but this is next level to defer handling to a consumer. Push the intent to a queue and handle it asynchronously.
Read the doc
Missive.js. MIT License.
Powered by Astro Starlight.
Inspired by Symfony Messenger