> ## 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.

<AgentInstructions>

## Submitting Feedback

If you encounter incorrect, outdated, or confusing documentation on this page, submit feedback:

POST https://docs.restate.dev/feedback

```json
{
  "path": "/guides/encore",
  "feedback": "Description of the issue"
}
```

Only submit feedback when you have something specific and actionable to report.

</AgentInstructions>

# Restate and Encore

> Learn how to run Restate service handlers inside an Encore TypeScript backend.

[Encore](https://encore.dev) is an open-source backend framework for TypeScript (and Go) with type-safe APIs,
declarative infrastructure, and built-in observability.
You can run Restate service handlers inside an Encore app by exposing them via
[raw endpoints](https://encore.dev/docs/ts/primitives/raw-endpoints), which give you direct access to the
Node.js request/response objects.

This lets you use Encore for your API layer, databases, and infrastructure while Restate handles durable execution.

<Info>
  **Prerequisites**

  * [The prerequisites for running Restate TS services](/get_started/quickstart)
</Info>

<Steps>
  <Step title="Create an Encore app">
    Follow the [Encore quickstart](https://encore.dev/docs/ts/quick-start) to install the CLI,
    then create a new app:

    ```shell theme={null}
    encore app create
    ```
  </Step>

  <Step title="Install the Restate SDK">
    Add the Restate TypeScript SDK to your Encore project:

    ```shell theme={null}
    npm install @restatedev/restate-sdk
    ```
  </Step>

  <Step title="Define your Restate service handlers">
    Create a Restate service with your handler logic. This is standard Restate code:

    ```ts order-processor/restate.ts {"CODE_LOAD::ts/src/guides/encore/restate.ts"}  theme={null}
    import * as restate from "@restatedev/restate-sdk";

    export const orderProcessor = restate.service({
        name: "OrderProcessor",
        handlers: {
            process: async (ctx: restate.Context, order: { id: string; item: string }) => {
                const confirmation = await ctx.run(() => chargePayment(order));
                await ctx.run(() => reserveInventory(order));
                await ctx.run(() => sendConfirmation(order, confirmation));
                return { status: "completed", orderId: order.id };
            },
        },
    });

    export type OrderProcessor = typeof orderProcessor;

    async function chargePayment(order: { id: string; item: string }) {
        console.log(`Charging payment for order ${order.id}`);
        return `conf-${order.id}`;
    }

    async function reserveInventory(order: { id: string; item: string }) {
        console.log(`Reserving inventory for ${order.item}`);
    }

    async function sendConfirmation(order: { id: string; item: string }, confirmation: string) {
        console.log(`Sending confirmation ${confirmation} for order ${order.id}`);
    }
    ```

    Each `ctx.run()` call is journaled by Restate. If the process crashes mid-execution, Restate replays completed
    steps and resumes where it left off.
  </Step>

  <Step title="Expose the handler via an Encore raw endpoint">
    Create the Encore service and wire the Restate endpoint handler to a raw endpoint.

    Since Encore's raw endpoints use Node.js HTTP types while the Restate SDK provides a Fetch API handler,
    we need a small adapter to bridge between the two:

    ```ts order-processor/encore.restate.ts {"CODE_LOAD::ts/src/guides/encore/encore.restate.ts"} theme={null}
    import { Service } from "encore.dev/service";
    export default new Service("order-processor");
    ```

    ```ts order-processor/api.ts {"CODE_LOAD::ts/src/guides/encore/api.ts"}  theme={null}
    import { api } from "encore.dev/api";
    import { createEndpointHandler } from "@restatedev/restate-sdk/fetch";
    import { orderProcessor } from "./restate";

    const handler = createEndpointHandler({
        services: [orderProcessor],
    });

    // Catch-all raw endpoint that Restate Server calls into
    export const restateEndpoint = api.raw(
        { expose: true, path: "/restate/!rest", method: "*" },
        async (req, resp) => {
            const url = new URL(req.url ?? "/", `http://${req.headers.host}`);
            const body =
                req.method !== "GET" && req.method !== "HEAD"
                    ? await new Promise<Buffer>((resolve, reject) => {
                        const chunks: Buffer[] = [];
                        req.on("data", (chunk: Buffer) => chunks.push(chunk));
                        req.on("end", () => resolve(Buffer.concat(chunks)));
                        req.on("error", reject);
                    })
                    : undefined;

            const webReq = new Request(url.toString(), {
                method: req.method,
                headers: req.headers as Record<string, string>,
                body,
            });

            const webResp = await handler(webReq);

            resp.writeHead(
                webResp.status,
                Object.fromEntries(webResp.headers.entries()),
            );
            const buf = await webResp.arrayBuffer();
            resp.end(Buffer.from(buf));
        },
    );
    ```

    Encore now serves the Restate handler at `/restate/*`. The Restate Server will call this
    endpoint to discover and invoke your handlers.
  </Step>

  <Step title="Start Restate Server and Encore">
    In one terminal, start the Restate Server:

    ```shell theme={null}
    restate-server
    ```

    In another terminal, start your Encore app:

    ```shell theme={null}
    encore run
    ```
  </Step>

  <Step title="Register your service with Restate">
    Tell the Restate Server where to find your handlers:

    ```shell theme={null}
    restate deployments register --use-http1.1 http://localhost:4000/restate
    ```

    You should see the discovered `OrderProcessor` service printed out.

    <Info>
      The `--use-http1.1` flag is needed because Encore's raw endpoints serve HTTP/1.1.
    </Info>
  </Step>

  <Step title="Invoke your handler">
    Send a request to Restate Server's ingress (port 8080), which routes it to your Encore-hosted handler:

    ```shell theme={null}
    curl localhost:8080/OrderProcessor/process \
      --json '{"id": "order-123", "item": "widget"}'
    ```

    You can also invoke the handler from other Encore API endpoints using the Restate client:

    ```ts order-processor/orders.ts {"CODE_LOAD::ts/src/guides/encore/orders.ts"}  theme={null}
    import { api } from "encore.dev/api";
    import * as restate from "@restatedev/restate-sdk-clients";
    import { OrderProcessor } from "./restate";

    const restateClient = restate.connect({ url: "http://localhost:8080" });

    export const createOrder = api(
        { method: "POST", path: "/orders", expose: true },
        async (req: { item: string }): Promise<{ orderId: string }> => {
            const orderId = `order-${Date.now()}`;
            await restateClient
                .serviceSendClient<OrderProcessor>({ name: "OrderProcessor" })
                .process({ id: orderId, item: req.item });
            return { orderId };
        },
    );
    ```
  </Step>

  <Step stepLabel="🎉" title="You're running Restate handlers inside Encore!" />
</Steps>

## Related resources

* [Encore documentation](https://encore.dev/docs/ts)
* [Encore raw endpoints](https://encore.dev/docs/ts/primitives/raw-endpoints)
* [`encore-restate-gen`](https://github.com/sebastianhindhede/encore-restate-gen): a CLI tool that auto-generates Restate service definitions and typed clients from your Encore project
* [Microservice orchestration use cases](/use-cases/microservice-orchestration)
* [Sagas guide](/guides/sagas)
