nest-temporal-client
v0.0.11
Published
NestJS module for sending signals, updates, queries, and starting Temporal workflows
Readme
nest-temporal-client
A NestJS module that wraps @temporalio/client to provide a single injectable service for interacting with Temporal workflows via gRPC — starting workflows, sending signals, running queries, and dispatching updates.
Installation
npm install nest-temporal-clientSetup
Register TemporalClientModule once in your root AppModule. It is globally scoped, so TemporalClientService is available anywhere in your application without re-importing.
Synchronous
import { TemporalClientModule } from 'nest-temporal-client';
@Module({
imports: [
TemporalClientModule.forRoot({
address: 'localhost:7233',
namespace: 'default',
}),
],
})
export class AppModule {}Asynchronous (with ConfigService)
import { TemporalClientModule } from 'nest-temporal-client';
@Module({
imports: [
TemporalClientModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (config: ConfigService) => ({
address: config.get('TEMPORAL_URL'),
namespace: config.get('TEMPORAL_NAMESPACE'),
}),
}),
],
})
export class AppModule {}Module options
| Option | Type | Default | Description |
|---|---|---|---|
| address | string | localhost:7233 | Temporal server gRPC address |
| namespace | string | default | Temporal namespace |
| tls | TLSConfig | — | TLS config for Temporal Cloud or secured servers |
Usage
Inject TemporalClientService into any service or controller.
import { TemporalClientService } from 'nest-temporal-client';
@Injectable()
export class OrderService {
constructor(private readonly temporal: TemporalClientService) {}
}API
startWorkflow(options)
Starts a new workflow execution and returns its workflowId.
const workflowId = await this.temporal.startWorkflow({
workflowName: 'processOrder',
workflowId: 'order-123',
taskQueue: 'orders',
args: [{ orderId: 'order-123' }],
});| Option | Type | Required | Description |
|---|---|---|---|
| workflowName | string | Yes | Name of the workflow function registered on the worker |
| workflowId | string | Yes | Unique ID for this workflow execution |
| taskQueue | string | Yes | Task queue the worker is listening on |
| args | unknown[] | No | Arguments to pass to the workflow function |
| workflowExecutionTimeout | Duration | No | Max time the entire workflow (including retries) may run |
| workflowRunTimeout | Duration | No | Max time a single workflow run may last |
| workflowTaskTimeout | Duration | No | Max time a single workflow task may take |
| cronSchedule | string | No | Cron expression for recurring executions |
| memo | Record<string, unknown> | No | Non-indexed metadata attached to the execution |
| runId | string | No | Optionally target a specific run |
signalWorkflow(options)
Sends a signal to a running workflow. Fire-and-forget — returns no value.
await this.temporal.signalWorkflow({
workflowId: 'order-123',
signalName: 'approve',
args: [{ approvedBy: 'admin' }],
});| Option | Type | Required | Description |
|---|---|---|---|
| workflowId | string | Yes | The ID of the workflow to signal |
| signalName | string | Yes | Name of the signal handler defined in the workflow |
| args | unknown[] | No | Arguments to pass to the signal handler |
| runId | string | No | Target a specific run of the workflow |
queryWorkflow<T>(options)
Queries a running or completed workflow and returns the result. Queries do not advance workflow state.
const status = await this.temporal.queryWorkflow<string>({
workflowId: 'order-123',
queryName: 'getStatus',
});| Option | Type | Required | Description |
|---|---|---|---|
| workflowId | string | Yes | The ID of the workflow to query |
| queryName | string | Yes | Name of the query handler defined in the workflow |
| args | unknown[] | No | Arguments to pass to the query handler |
| runId | string | No | Target a specific run of the workflow |
updateWorkflow<T>(options)
Sends an update to a running workflow and waits for the result. Unlike signals, updates can be validated by the workflow and return a value.
const newCount = await this.temporal.updateWorkflow<number>({
workflowId: 'order-123',
updateName: 'addItem',
args: [{ itemId: 'sku-456', quantity: 2 }],
});| Option | Type | Required | Description |
|---|---|---|---|
| workflowId | string | Yes | The ID of the workflow to update |
| updateName | string | Yes | Name of the update handler defined in the workflow |
| args | unknown[] | No | Arguments to pass to the update handler |
| runId | string | No | Target a specific run of the workflow |
cancelWorkflow(options)
Requests graceful cancellation. The workflow receives a CancelledFailure and can perform cleanup before stopping.
await this.temporal.cancelWorkflow({ workflowId: 'order-123' });| Option | Type | Required | Description |
|---|---|---|---|
| workflowId | string | Yes | The ID of the workflow to cancel |
| runId | string | No | Target a specific run of the workflow |
terminateWorkflow(options)
Forcefully terminates a workflow immediately, bypassing any cleanup logic.
await this.temporal.terminateWorkflow({
workflowId: 'order-123',
reason: 'manual intervention',
});| Option | Type | Required | Description |
|---|---|---|---|
| workflowId | string | Yes | The ID of the workflow to terminate |
| reason | string | No | Human-readable reason recorded in the event history |
| runId | string | No | Target a specific run of the workflow |
describeWorkflow(options)
Returns metadata and current state of a workflow execution.
const info = await this.temporal.describeWorkflow({ workflowId: 'order-123' });
console.log(info.status.name); // RUNNING, COMPLETED, FAILED, etc.| Option | Type | Required | Description |
|---|---|---|---|
| workflowId | string | Yes | The ID of the workflow to describe |
| runId | string | No | Target a specific run of the workflow |
getHandle(options)
Returns a raw WorkflowHandle for advanced use cases where you need to chain multiple operations on the same execution.
const handle = this.temporal.getHandle({ workflowId: 'order-123' });
const result = await handle.result();