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.
- 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
QueueHandlerschema to provide autocompletion and validation when sending messages. - Automatic Log Finalization: If a
finalizeLogHandleris specified, the middleware automatically "dumps" the currentLoggerstate into the queue after the request finishes. - Trace Propagation: Automatically carries over
parentEventIdandlanguagevariables into queue messages to maintain distributed tracing and localization.
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!');
});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());| 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. |
- Environment Binding: The
nameprovided must exist in yourenvas a Cloudflare Queue binding. - Middleware Order: If using
finalizeLogHandler, theloggermiddleware must be registered before thequeuemiddleware so that a logger instance is available in the context.
Every message sent via the producer generated by this middleware automatically includes:
parentEventId: Set to the current request'seventId(if logger is present), ensuring background tasks are linked to the HTTP request that triggered them.language: Propagates the current user's language setting to the background worker.
- Setup: The middleware retrieves the Queue binding and the current
language/loggerfrom the context. - Injection: It creates a producer using
queueHandler.getProducerand saves it to the Hono context under the providedname. - Next: The request moves to the next middleware or route handler.
- Finalization: Once the response is ready and the stack "unwinds," the middleware checks for
finalizeLogHandler. If it exists, it callslogger.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.