Documentation Index
Fetch the complete documentation index at: https://docs.restate.dev/llms.txt
Use this file to discover all available pages before exploring further.
An invocation is a request to execute a handler.
The Restate SDK client library lets you invoke Restate handlers from anywhere in your application.
Use this only in non-Restate services without access to the Restate Context.
Each invocation has its own unique ID and lifecycle.
Have a look at managing invocations to learn how to manage the lifecycle of an invocation.
Installation
First, add the dependency to your project
npm install @restatedev/restate-sdk-clients
Then, register the service you want to invoke.
Finally, connect to Restate and invoke the handler with your preferred semantics.
Request-response invocations
To wait on a response from the handler:
// import * as clients from "@restatedev/restate-sdk-clients";
const restateClient = clients.connect({ url: "http://localhost:8080" });
// To call a service
const greet = await restateClient
.serviceClient<MyService>({ name: "MyService" })
.greet({ greeting: "Hi" });
// To call an object
const count = await restateClient
.objectClient<MyObject>({ name: "MyObject" }, "Mary")
.greet({ greeting: "Hi" });
// To call a workflow
const handle = await restateClient
.workflowClient<MyWorkflow>({ name: "MyWorkflow" }, "someone")
.workflowSubmit({ greeting: "Hi" });
const result = await restateClient.result(handle);
const status = await restateClient
.workflowClient<MyWorkflow>({ name: "MyWorkflow" }, "someone")
.myOtherHandler();
One-way invocations
To send a message without waiting for a response:
// import * as clients from "@restatedev/restateClient-sdk-clients";
const restateClient = clients.connect({ url: "http://localhost:8080" });
// To send a message to a service
await restateClient
.serviceSendClient<MyService>({ name: "MyService" })
.greet({ greeting: "Hi" });
// To send a message to an object
await restateClient
.objectSendClient<MyObject>({ name: "MyObject" }, "Mary")
.greet({ greeting: "Hi" });
// To send a message to a workflow
const handle = await restateClient
.workflowClient<MyWorkflow>({ name: "MyWorkflow" }, "someone")
.workflowSubmit({ greeting: "Hi" });
// You cannot send a message to a shared handler in a workflow
Delayed invocations
To schedule an invocation for a later point in time:
// import * as clients from "@restatedev/restate-sdk-clients";
const restateClient = clients.connect({ url: "http://localhost:8080" });
// To send a delayed message to a service
await restateClient
.serviceSendClient<MyService>({ name: "MyService" })
.greet({ greeting: "Hi" }, clients.rpc.sendOpts({ delay: { seconds: 1 } }));
// To send a delayed message to an object
await restateClient
.objectSendClient<MyObject>({ name: "MyObject" }, "Mary")
.greet({ greeting: "Hi" }, clients.rpc.sendOpts({ delay: { seconds: 1 } }));
// To send a delayed message to a workflow
const handle = await restateClient
.workflowClient<MyWorkflow>({ name: "MyWorkflow" }, "someone")
.workflowSubmit(
{ greeting: "Hi" },
clients.rpc.sendOpts({ delay: { seconds: 1 } })
);
// You cannot send a delayed message to a shared handler in a workflow
Invoke a handler idempotently
By using Restate and an idempotency key, you can make any service call idempotent, without any extra code or setup. This is a very powerful feature to ensure that your system stays consistent and doesn’t perform the same operation multiple times.
To make a service call idempotent, you can use the idempotency key feature.
Add the idempotency key to the header via:
await restateClient
.serviceSendClient<MyService>({ name: "MyService" })
.greet(request, clients.rpc.sendOpts({ idempotencyKey: "abcde" }));
After the invocation completes, Restate persists the response for a retention period of one day (24 hours).
If you re-invoke the service with the same idempotency key within 24 hours, Restate sends back the same response and doesn’t re-execute the request to the service.
The call options, with which we set the idempotency key, also let you add other headers to the request.
Retrieve result of invocations and workflows
You can use the client library to retrieve the results of invocations with an idempotency key or workflows.
Attach to an invocation with an idempotency key
For invocations with an idempotency key, you can attach to the invocation and wait for it to finish:
// import * as clients from "@restatedev/restate-sdk-clients";
const restateClient = clients.connect({ url: "http://localhost:8080" });
// To send a message
const handle = await restateClient
.serviceSendClient<MyService>({ name: "MyService" })
.greet(request, clients.rpc.sendOpts({ idempotencyKey: "abcde" }));
// ... do something else ...
// Attach later to retrieve the result
const response = await restateClient.result(handle);
Attach/peek at a workflow execution
For workflows, you can attach to the workflow execution and wait for it to finish or peek at the output:
// import * as clients from "@restatedev/restate-sdk-clients";
const restateClient = clients.connect({ url: "http://localhost:8080" });
// Option 1: attach and wait for result with workflow ID
const result = await restateClient
.workflowClient<MyWorkflow>({ name: "MyWorkflow" }, "someone")
.workflowAttach();
// Option 2: peek to check if ready with workflow ID
const peekOutput = await restateClient
.workflowClient<MyWorkflow>({ name: "MyWorkflow" }, "someone")
.workflowOutput();
if (peekOutput.ready) {
const result2 = peekOutput.result;
}
Advanced: sharing service type definitions
Have a look at the options listed in the Service Communication docs. These are also valid for the SDK clients.