Skip to main content

Manage Interceptors - TypeScript SDK

Interceptors are SDK hooks that let you intercept inbound and outbound Temporal calls. You use them to apply shared behavior across many calls, such as tracing and authorization, before calls reach the SDK's underlying implementation. This is similar to middleware in other frameworks.

How to implement interceptors in TypeScript

The TypeScript SDK comes with an optional interceptor package that adds tracing with OpenTelemetry. See how to use it in the interceptors-opentelemetry code sample.

Interceptors are run in a chain, and all interceptors work similarly. They accept two arguments: input and next, where next calls the next interceptor in the chain. All interceptor methods are optional—it's up to the implementor to choose which methods to intercept.

Interceptor examples

Log start and completion of Activities

import { ActivityInput, Next, WorkflowOutboundCallsInterceptor } from '@temporalio/workflow';

export class ActivityLogInterceptor implements WorkflowOutboundCallsInterceptor {
constructor(public readonly workflowType: string) {}

async scheduleActivity(
input: ActivityInput,
next: Next<WorkflowOutboundCallsInterceptor, 'scheduleActivity'>
): Promise<unknown> {
console.log('Starting activity', { activityType: input.activityType });
try {
return await next(input);
} finally {
console.log('Completed activity', {
workflow: this.workflowType,
activityType: input.activityType,
});
}
}
}

Register an Interceptor

Registering an interceptor means providing it to the SDK so Temporal can invoke it when matching Client, Worker, or Workflow-isolate calls occur. Once registered, it runs in the call path and can observe or modify request and response data.

Register via a Plugin

If you're building a reusable library or want to bundle interceptors with other primitives, you can register them through a Plugin.

Activity and client interceptors registration

Workflow interceptors registration

Workflow interceptor registration is different from the other interceptors because they run in the Workflow isolate. To register Workflow interceptors, export an interceptors function from a file located in the workflows directory and provide the name of that file to the Worker on creation via WorkerOptions.

At the time of construction, the Workflow context is already initialized for the current Workflow. You may call the workflowInfo() function to access Workflow-specific information from an interceptor.

src/workflows/your-interceptors.ts

import { workflowInfo } from '@temporalio/workflow';

export const interceptors = () => ({
outbound: [new ActivityLogInterceptor(workflowInfo().workflowType)],
inbound: [],
});

src/worker/index.ts

const worker = await Worker.create({
workflowsPath: require.resolve('./workflows'),
interceptors: {
workflowModules: [require.resolve('./workflows/your-interceptors')],
},
});