Skip to content

Middleware API

The Middleware interface allows you to inject cross-cutting concerns into workflow execution. Middleware can wrap node executions, run before or after nodes, and is essential for features like observability, transactions, and logging.

Interface Definition

typescript
export interface Middleware<TContext extends Record<string, any> = Record<string, any>> {
	beforeNode?: (ctx: ContextImplementation<TContext>, nodeId: string) => void | Promise<void>
	afterNode?: (
		ctx: ContextImplementation<TContext>,
		nodeId: string,
		result: NodeResult | undefined,
		error: Error | undefined,
	) => void | Promise<void>
	aroundNode?: (
		ctx: ContextImplementation<TContext>,
		nodeId: string,
		next: () => Promise<NodeResult>,
	) => Promise<NodeResult>
}

Hooks

beforeNode

Runs before a node executes. Useful for setup or logging.

  • Parameters:
    • ctx: The workflow context
    • nodeId: The ID of the node about to execute

afterNode

Runs after a node executes, regardless of success or failure.

  • Parameters:
    • ctx: The workflow context
    • nodeId: The ID of the executed node
    • result: The result of the node execution (undefined if error)
    • error: The error thrown (undefined if success)

aroundNode

Wraps the entire node execution. This is the most powerful hook as it can control the execution flow.

  • Parameters:
    • ctx: The workflow context
    • nodeId: The ID of the node being executed
    • next: Function to call to proceed with execution
  • Returns: The NodeResult from the node or modified result

Usage with FlowRuntime

Middleware is provided to the FlowRuntime constructor:

typescript
const runtime = new FlowRuntime({
  middleware: [myMiddleware1, myMiddleware2],
})

Middleware executes in LIFO order (last in, first out).

Built-in Middleware

For examples, see the Middleware Guide.

Released under the MIT License