Skip to main content

TypeScript quickstart

  1. Setup your app folder
    mkdir hello-reboot && cd hello-reboot
  2. Install Reboot
    npm init -y && npm pkg set type="module" && npm install @reboot-dev/reboot && npx tsc --init --sourceMap --declaration --module nodenext --moduleResolution nodenext --target es2020 --rootDir . --outDir dist
  3. Create a .proto file
    mkdir -p ./api/hello/v1 && touch ./api/hello/v1/hello.proto
  4. Define your durable state data types and operations
    syntax = "proto3";

    package hello.v1;

    import "rbt/v1alpha1/options.proto";

    message Hello {
    option (rbt.v1alpha1.state) = {};
    repeated string messages = 1;
    }

    service HelloInterface {
    rpc Messages(MessagesRequest) returns (MessagesResponse) {
    option (rbt.v1alpha1.method).reader = {};
    }

    rpc Send(SendRequest) returns (SendResponse) {
    option (rbt.v1alpha1.method).writer = {};
    }
    }

    message MessagesRequest {}

    message MessagesResponse {
    repeated string messages = 1;
    }

    message SendRequest {
    string message = 1;
    }

    message SendResponse {}
  5. Create .ts implementation file
    mkdir -p ./backend/src && touch ./backend/src/hello_servicer.ts
  6. Implement HelloServicer
    import { ReaderContext, WriterContext } from "@reboot-dev/reboot";

    import {
    Hello,
    MessagesRequest,
    SendRequest,
    } from "../../api/hello/v1/hello_rbt.js";

    export class HelloServicer extends Hello.Interface {
    async messages(
    context: ReaderContext,
    state: Hello.State,
    request: MessagesRequest
    ) {
    return { messages: state.messages };
    }

    async send(
    context: WriterContext,
    state: Hello.State,
    request: SendRequest
    ) {
    state.messages.push(request.message);
    return {};
    }
    }
  7. Create a main entrypoint
    touch ./backend/src/main.ts
  8. Implement main.ts
    import { Application, ExternalContext } from "@reboot-dev/reboot";
    import { Hello } from "../../api/hello/v1/hello_rbt.js";
    import { HelloServicer } from "./hello_servicer.js";

    const initialize = async (context: ExternalContext) => {
    const hello = Hello.lookup("hello-reboot");

    const response = await hello
    .idempotently()
    .send(context, { message: "Hello, World!" });
    };

    new Application({
    servicers: [HelloServicer],
    initialize,
    }).run();
  9. Create an .rbtrc file
    touch .rbtrc
  10. Add necessary flags to your .rbtrc file
    protoc api/
    protoc --nodejs=api/

    dev run --name=hello
    dev run --tsc='npx tsc'
    dev run --watch=backend/src/**/*.ts
    dev run --nodejs
    dev run --application=dist/backend/src/main.js
  11. Run your app
    npx rbt dev run
  12. Query your app
    curl -XPOST https://dev.localhost.direct:9991/hello.v1.HelloInterface/Messages \
    -H "x-reboot-state-ref:hello.v1.Hello:hello-reboot"

Summary

In this example, you:

  1. Defined a Reboot durable state data type.
  2. Defined and implemented the operations on your data type.
  3. Built your Reboot app and ran it.

This example is somewhat contrived as we only created one instance of your Hello data type, but in practice you are free to make as many of these as you like!

So far, we've covered reader and writer methods but Reboot's real power is in transactions. Learn about transactions and all of the other available method kinds here.

Hopefully, your wheels are starting to spin thinking of all of the possibilities!

Next steps