Run your application
Reboot applications are defined using an instance of Application
, and launched from the file
configured as your --application
in .rbtrc
.
Application
Your entrypoint will construct an Application
and then run
it:
- Python
- TypeScript
async def main():
await Application(
servicers=[HelloServicer],
initialize=initialize,
).run()
if __name__ == '__main__':
asyncio.run(main())
new Application({
servicers: [HelloServicer],
initialize,
}).run();
initialize
functions
The optional initialize
argument to the Application
constructor is a function that
runs every time your application starts up.
Initializers can be used to create any initial state that your application needs. In particular, they are usually where any singleton instances used by your application are created.
- Python
- TypeScript
async def initialize(context: InitializeContext):
hello = Hello.ref(EXAMPLE_STATE_MACHINE_ID)
# Implicitly construct state machine upon first write.
await hello.send(
context,
message="Hello, World!",
)
const initialize = async (context) => {
const hello = Hello.ref("hello-nodejs");
await hello.send(context, { message: "Hello, World!" });
};
If you have declared an initialize
function, then you can additionally pass an
initialize_bearer_token
(initializeBearerToken
in TypeScript) which the initialize
method
should use to authenticate itself to your application.
HTTP custom routes
Using a Reboot Application
you can not only run your Reboot
servicers but you can also
provide custom HTTP route handlers for circumstances where you can't
just call one of your data type's methods.
For Python, this is implemented using FastAPI. For TypeScript, this is implemented with Express.js.
Limitations of custom HTTP routes
-
Currently only
GET
andPOST
methods are supported. -
The
/
route is currently used by Reboot itself to show a helpful page explaining that this is a Reboot application.
Please reach out to us at team@reboot.dev if you run into use cases for fixing these!
Here is an example of implementing a handler for an HTTP GET
:
- Python
- TypeScript
@application.http.get("/hello_world")
def hello_world():
return {"message": "Hello, world!"}
const application = new Application({ servicers: [GreeterServicer] });
application.http.get("/hello_world", async (context, req, res) => {
res.json({ message: `Hello, world!` });
});
To simplify calling directly into your Reboot application from your
application.http.get
and application.http.post
handlers we provide
a context
of type
ExternalContext
because
you are still "external" to your application from an authorization
perspective.
This context
includes any bearer token from
Authorization: Bearer <token>
so that any calls into your Reboot application
will be properly authorized. In TypeScript, we inject the context for every
handler. In Python, we follow the FastAPI dependency injection strategy.
If you want the context
, you must explicitly add it to your arguments as shown in
the following example:
- Python
- TypeScript
@application.http.post("/hello_greeter")
async def hello_greeter(
request: Request,
context: ExternalContext = InjectExternalContext,
):
body = await request.json()
greeter, _ = await Greeter.create(
context,
title=body['title'],
name=body['name'],
adjective=body['adjective'],
)
response = await greeter.greet(context, name="You")
return {"message": response.message}
const application = new Application({ servicers: [GreeterServicer] });
application.http.post("/hello_greeter", async (context, req, res) => {
const { title, name, adjective } = req.body as {
title: string;
name: string;
adjective: string;
};
const [greeter] = await Greeter.create(context, {
title,
name,
adjective,
});
const { message } = await greeter.greet(context, { name: "You" });
res.json({ message });
});