- Request-response calls: Call and wait for a response
- One-way messages: Send a message and continue
- Delayed messages: Send a message after a delay
To call a service from an external application, see the HTTP, Kafka, or SDK Clients documentation.
Request-response calls
To call a Restate handler and wait for its result:Workflow retention
Workflow retention
After a workflow’s run handler completes, other handlers can still be called for up to 24 hours (default).
Update this via the service configuration.
Request-response calls between exclusive handlers of Virtual Objects may lead to deadlocks:
- Cross deadlock: A → B and B → A (same keys).
- Cycle deadlock: A → B → C → A.
Sending messages
To send a message to another Restate handler without waiting for a response:Calls to a Virtual Object execute in order of arrival, serially.
Example:Call A is guaranteed to execute before B. However, other invocations may interleave between A and B.
Delayed messages
To send a message after a delay:Learn how this is different from sleeping and then sending a message.
Using an idempotency key
To prevent duplicate executions of the same call, add an idempotency key:Attach to an invocation
To wait for or get the result of a previously sent message:- With an idempotency key: Wait for completion and retrieve the result.
- Without an idempotency key: Can only wait, not retrieve the result.
Signals
Signals let invocations communicate directly with each other: one invocation waits for a named signal, and any other handler can resolve or reject it by referencing the target invocation’s ID. Waiting for a signal (inside the invocation that wants to pause):ctx.request().id. Pass it to other handlers using state, awakeables, or any other mechanism you prefer.
Each invocation can wait on multiple distinct signal names at the same time. Signals are scoped to the invocation — the same name on different invocations is independent.
Signals require restate-server 1.7 with
RESTATE_EXPERIMENTAL_ENABLE_PROTOCOL_V7=true enabled.InvocationReference
ctx.invocation(invocationId) returns an InvocationReference that lets you interact with any other invocation by its ID:
Cancel an invocation
To cancel a running handler, useInvocationReference:
ctx.cancel() (deprecated):
Advanced: sharing service type definitions
When calling services, you need access to their type definitions for type safety. Here are four approaches to share service definitions without exposing implementation details:Option 1: Export type-only service definition
Option 1: Export type-only service definition
Export only the service type information from where you define your service:Import and use this definition in calling handlers:
Option 2: Define service interface manually
Option 2: Define service interface manually
Create a TypeScript interface matching the service’s handler signatures. Useful when the service is in a different language or when you can’t import the type definition:
Option 3: Import as dev dependency
Option 3: Import as dev dependency
When your service is published as a separate package, import it as a dev dependency to access its types:
See also
- SDK Clients: Call Restate services from external applications
- Error Handling: Handle failures and terminal errors in service calls
- Durable Timers: Implement timeouts for your service calls
- Serialization: Customize how data is serialized between services
- Sagas: Roll back or compensate for canceled service calls.