TypeScript
- Setup your app folder
mkdir reboot-hello && cd reboot-hello
- Install Reboot
npm init -y && npm pkg set type="module" && npm install @reboot-dev/reboot && npx tsc --init --sourceMap --declaration --moduleResolution node --target es2020 --rootDir . --outDir dist
- Define your API using Zod
mkdir -p ./api/hello/v1 && touch ./api/hello/v1/hello.ts
- Define your durable state data types and operations
// ./api/hello/v1/hello.ts
import { z } from "zod/v4";
export const api = {
Hello: {
state: {
messages: z.array(z.string()).default(() => []).meta({ tag: 1 }),
},
methods: {
messages: {
kind: "reader",
request: {},
response: {
messages: z.array(z.string()).meta({ tag: 1 }),
},
},
send: {
kind: "writer",
request: {
message: z.string().meta({ tag: 1 }),
},
response: {},
},
},
},
}; - Create
.ts
implementation filemkdir -p ./backend/src && touch ./backend/src/hello_servicer.ts
- Implement
HelloServicer
- Object literal
- Class
import { ReaderContext, WriterContext } from "@reboot-dev/reboot";
import { Hello } from "../../api/hello/v1/hello_rbt.js";
export const helloServicer = Hello.servicer({
messages: async (
context: ReaderContext,
state: Hello.State,
request: Hello.MessagesRequest
): Promise<Hello.MessagesResponse> => {
return { messages: state.messages };
},
send: async (
context: WriterContext,
state: Hello.State,
request: Hello.SendRequest
): Promise<[Hello.State, Hello.SendResponse]> => {
state.messages.push(request.message);
return [state, {}];
},
});// ./backend/src/hello_servicer.ts
import { ReaderContext, WriterContext } from "@reboot-dev/reboot";
import { Hello } from "../../api/hello/v1/hello_rbt.js";
export class HelloServicer extends Hello.Servicer {
async messages(
context: ReaderContext,
request: Hello.MessagesRequest
): Promise<Hello.MessagesResponse> {
return { messages: this.state.messages };
}
async send(
context: WriterContext,
request: Hello.SendRequest
): Promise<Hello.SendResponse> {
this.state.messages.push(request.message);
return {};
}
} - Create a
main
entrypointtouch ./backend/src/main.ts
- Implement
main.ts
- Object literal
- Class
import { Application, InitializeContext } from "@reboot-dev/reboot";
import { Hello } from "../../api/hello/v1/hello_rbt.js";
import { helloServicer } from "./hello_servicer.js";
const initialize = async (context: InitializeContext) => {
const hello = Hello.ref("reboot-hello");
await hello.send(context, { message: "Hello, World!" });
};
new Application({
servicers: [helloServicer],
initialize,
}).run();// ./backend/src/main.ts
import { Application, InitializeContext } from "@reboot-dev/reboot";
import { Hello } from "../../api/hello/v1/hello_rbt.js";
import { HelloServicer } from "./hello_servicer.js";
const initialize = async (context: InitializeContext) => {
const hello = Hello.ref("reboot-hello");
await hello.send(context, { message: "Hello, World!" });
};
new Application({
servicers: [HelloServicer],
initialize,
}).run(); - Create an
.rbtrc
filetouch .rbtrc
- Add necessary flags to your
.rbtrc
file# .rbtrc
generate api/
generate --nodejs=api/
dev run --name=hello
dev run --watch=backend/src/**/*.ts
dev run --nodejs
dev run --application=backend/src/main.ts - Run your app
npx rbt dev run
- Query your app
curl -XPOST http://localhost:9991/hello.v1.HelloMethods/Messages \
-H "x-reboot-state-ref:hello.v1.Hello:reboot-hello"
Next steps
Well done! You made 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!
Check out these links to continue your exploration:
- Build a React frontend - create a React frontend that connects to your backend and displays your messages in real-time.
- Learn about transactions - so far,
we've covered
reader
andwriter
methods, but Reboot's power extends totransactions
. Learn abouttransactions
and all of the other method kinds here. - Join us on Discord - to ask questions and let us know what you think!
Hopefully, your wheels are starting to spin thinking of all of the possibilities!