Events

Custom Event Adapter

Build a custom event transport adapter to distribute VitNode domain events across multiple instances via message brokers like Redis Streams or RabbitMQ.

By default, VitNode delivers domain events in-process on the originating machine. By implementing a custom EventsApiPlugin, you can forward events to an external message broker (Redis Streams, RabbitMQ, NATS) to fan them out across a distributed cluster.

The EventsApiPlugin Interface

import type { Context } from "hono"
import type { EventEnvelope, EventEmitResult } from "@vitnode/core/api/models/events"

export interface EventsApiPlugin {
  name: string
  publish: (c: Context, envelope: EventEnvelope) => Promise<EventEmitResult>
}

Quick start

1. Build the Adapter

apps/api/src/lib/events/redis-stream-adapter.ts
import type { EventsApiPlugin } from "@vitnode/core/api/models/events"

export const RedisStreamEventsAdapter = (): EventsApiPlugin => ({
  name: "redis-stream",
  publish: async (c, envelope) => {
    const redis = c.get("redis")
    if (redis) {
      await redis.xadd("vitnode:events", "*", "payload", JSON.stringify(envelope))
    }

    return {
      eventId: envelope.eventId,
      status: "queued",
      delivered: 0,
      failures: [],
    }
  },
})

2. Register in API Configuration

apps/api/src/vitnode.api.config.ts
import { buildApiConfig } from "@vitnode/core/vitnode.config"
import { RedisStreamEventsAdapter } from "./lib/events/redis-stream-adapter"

export const vitNodeApiConfig = buildApiConfig({
  events: {
    adapter: RedisStreamEventsAdapter(),
  },
})

All calls to c.get("events").emit() will now publish events through your custom adapter.

Learn More