Skip to main content

Clients

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.

Copy code templates via the UI Playground

The UI helps you with invoking your services programmatically. Open the UI at port 9070, register your service, click on the service, open the playground, and copy over the code snippet to invoke your service in your preferred language.

Use the Restate Context

Always invoke handlers via the context, if you have access to it. Restate then attaches information about the invocation to the parent invocation.

Invoking handlers with the SDK clients

1
Add the dependency to your project

Language of the next code block: shellscript

npm install @restatedev/restate-sdk-clients

2
Register the service you want to invoke.

3
Connect to Restate and invoke the handler with your preferred semantics

Request-response invocations allow you to wait on a response from the handler.

Language of the next code block: typescript

// import * as clients from "@restatedev/restate-sdk-clients";
const rs = clients.connect({ url: "http://localhost:8080" });
const greet = await rs
.serviceClient(greeterService)
.greet({ greeting: "Hi" });
const count = await rs
.objectClient(greetCounterObject, "Mary")
.greet({ greeting: "Hi" });

One-way invocations allow you to send a message without waiting for a response.

Language of the next code block: typescript

// import * as clients from "@restatedev/restate-sdk-clients";
const rs = clients.connect({ url: "http://localhost:8080" });
await rs.serviceSendClient(greeterService).greet({ greeting: "Hi" });
await rs
.objectSendClient(greetCounterObject, "Mary")
.greet({ greeting: "Hi" });

Delayed invocations allow you to schedule an invocation for a later point in time.

Language of the next code block: typescript

// import * as clients from "@restatedev/restate-sdk-clients";
const rs = clients.connect({ url: "http://localhost:8080" });
await rs
.serviceSendClient(greeterService)
.greet({ greeting: "Hi" }, clients.rpc.sendOpts({ delay: 1000 }));
await rs
.objectSendClient(greetCounterObject, "Mary")
.greet({ greeting: "Hi" }, clients.rpc.sendOpts({ delay: 1000 }));

Invoke a handler idempotently

To make a service call idempotent, you can use the idempotency key feature. Add the idempotency key to the header via:

Language of the next code block: typescript

await rs
.serviceSendClient(greeterService)
.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.

Make any service call idempotent by using Restate

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.

Adding headers to the request

The call options, with which we set the idempotency key, also let you add other headers to the request.

Tuning retention time

You can tune the retention time] on a service-level by using the [Admin API] (docs):

Language of the next code block: shellscript

curl -X PATCH localhost:9070/services/MyService --json '{"idempotency_retention": "2days"}'

The retention time is in humantime format.

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 them by using the handle that is returned from the invocation:

Language of the next code block: typescript

// import * as clients from "@restatedev/restate-sdk-clients";
const rs = clients.connect({ url: "http://localhost:8080" });
// Send a message
const handle = await rs
.serviceSendClient(greeterService)
.greet(request, clients.rpc.sendOpts({ idempotencyKey: "abcde" }));
// ... do something else ...
// Attach later to retrieve the result
const response = await rs.result(handle);