Skip to content

Latest commit

 

History

History
113 lines (78 loc) · 4.33 KB

File metadata and controls

113 lines (78 loc) · 4.33 KB

Queue Producer Middleware

The queue middleware facilitates type-safe communication between your Hono API and Cloudflare Queues. It dynamically injects a typed producer into the request context and optionally automates "finalize logging" by dumping the request's log state into the queue once the response is complete.


Features

  • Context-Aware Injection: Dynamically binds a queue producer to the Hono context using the binding name defined in your wrangler.toml.
  • Type-Safe Messaging: Leverages your existing QueueHandler schema to provide autocompletion and validation when sending messages.
  • Automatic Log Finalization: If a finalizeLogHandler is specified, the middleware automatically "dumps" the current Logger state into the queue after the request finishes.
  • Trace Propagation: Automatically carries over parentEventId and language variables into queue messages to maintain distributed tracing and localization.

Usage

1. Basic Setup

Attach the middleware to your Hono instance. You must pass the name of the binding and your pre-configured QueueHandler.

import { Hono } from 'hono';
import { queue } from './middleware/queue';
import { queueHandler } from './queue/config';

const app = new Hono();

app.use(
  '/api/*',
  queue({
    name: 'MY_QUEUE',
    queueHandler: queueHandler,
  })
);

app.post('/process', async (c) => {
  const producer = c.get('MY_QUEUE');

  // Fully typed based on your QueueHandler schema
  await producer('email', {
    to: 'user@example.com',
    subject: 'Hello!',
    body: 'Hello, this is a test email.',
  });

  return c.text('Queued!');
});

2. Automated Logging (Post-Processing)

By combining this with the logger middleware, you can offload log persistence to a background worker.

// 1. Initialize Logger
app.use('*', logger({ service: 'api' }));

// 2. Initialize Queue with log finalizer
app.use(
  '*',
  queue({
    name: 'LOG_QUEUE',
    queueHandler: logQueueHandler,
    finalizeLogHandler: 'persist_log', // The handler key in your schema
  })
);

// After next() finishes, the middleware automatically calls:
// await producer('persist_log', logger.dump());

API Reference

queue(options)

Option Type Description
name string The environment binding name for the Queue (e.g., 'MY_QUEUE').
queueHandler QueueHandler An instance of the QueueHandler class defining your message schema.
finalizeLogHandler string (Optional) The key in your schema used for auto-logging the request state.

Technical Details

Dependency Requirements

  • Environment Binding: The name provided must exist in your env as a Cloudflare Queue binding.
  • Middleware Order: If using finalizeLogHandler, the logger middleware must be registered before the queue middleware so that a logger instance is available in the context.

Message Metadata

Every message sent via the producer generated by this middleware automatically includes:

  1. parentEventId: Set to the current request's eventId (if logger is present), ensuring background tasks are linked to the HTTP request that triggered them.
  2. language: Propagates the current user's language setting to the background worker.

Logic Flow

  1. Setup: The middleware retrieves the Queue binding and the current language/logger from the context.
  2. Injection: It creates a producer using queueHandler.getProducer and saves it to the Hono context under the provided name.
  3. Next: The request moves to the next middleware or route handler.
  4. Finalization: Once the response is ready and the stack "unwinds," the middleware checks for finalizeLogHandler. If it exists, it calls logger.dump() and pushes that data to the queue.

Note

The finalizeLogHandler is executed using await. If your queue is experiencing heavy backpressure or latency, this may slightly delay the final response settlement of the worker, though it occurs after the business logic has finished.