Skip to main content

Serving

Restate services can run in a few ways: as a Node.js HTTP handler, as a AWS Lambda handler, or on other Javascript runtimes like Bun, Deno and Cloudflare Workers.

Creating an Node.js HTTP handler

  1. Create the endpoint
  2. Bind one or multiple services to it.
  3. Listen on the specified port (default 9080) for connections and requests.

import * as restate from "@restatedev/restate-sdk";
restate
.endpoint()
.bind(myService)
.bind(myVirtualObject)
.bind(myWorkflow)
.listen();

Customizing the HTTP2 server

If you need to manually control or customize the HTTP2 server, you can call http2Handler() instead of listen(), and then use it to manually instantiate the HTTP server:


const http2Handler = restate
.endpoint()
.bind(myService)
.bind(myVirtualObject)
.bind(myWorkflow)
.http2Handler();
const httpServer = http2.createServer(http2Handler);
httpServer.listen();

Creating a Lambda handler

To register your service as a Lambda function, use the /lambda import component and change the endpoint into a Lambda handler.


import * as restate from "@restatedev/restate-sdk/lambda";
export const handler = restate
.endpoint()
.bind(myService)
.bind(myVirtualObject)
.bind(myWorkflow)
.handler();

Have a look at the deployment section for guidance on how to deploy your services on AWS Lambda.

Run on Lambda without handler changes

The implementation of your services and handlers remains the same for both deployment options.

Creating a fetch handler

Other Javascript runtimes like Deno, Bun and Cloudflare Workers have build on top of the Fetch Standard for defining HTTP server handlers. To register your service as a fetch handler, use the /fetch import component.


import * as restate from "@restatedev/restate-sdk/fetch";
const handler = restate
.endpoint()
.bind(myService)
.bind(myVirtualObject)
.bind(myWorkflow)
.handler();
// Cloudflare expects the handler as a default export
export default handler;
// Bun expects an object containing the inner fetch function
Bun.serve({
port: 9080,
...handler,
});
// Deno expects to be passed the fetch function
Deno.serve({ port: 9080 }, handler.fetch);

By default, a fetch handler will not advertise itself as working bidirectionally; the SDK will end the HTTP request at each suspension point, and the Restate runtime will re-invoke the service when there is more work to do.

However, you can use the method .bidirectional() on the endpoint builder to change this on supported platforms, which will improve latencies once the service is re-registered with the runtime.

  • Deno and Deno Deploy support HTTP2 and therefore bidirectional mode can be enabled.
  • Bun does not yet support HTTP2, but its HTTP1.1 implementation does support bidirectional communication, as long as there is not a buffering load balancer between the client and the Bun server. Bun services must be discovered with the --use-http1.1 CLI flag.
  • Cloudflare Workers do not support end-to-end HTTP2 or bidirectional HTTP1.1, and enabling bidirectional mode will cause invocations to stall and time out. Services running on Workers must be must be discovered with the --use-http1.1 CLI flag.

Validating request identity

SDKs can validate that incoming requests come from a particular Restate instance. You can find out more about request identity in the Security docs


restate
.endpoint()
.bind(myService)
.bind(myVirtualObject)
.bind(myWorkflow)
.withIdentityV1("publickeyv1_w7YHemBctH5Ck2nQRQ47iBBqhNHy4FV7t2Usbye2A6f")
.listen();