Exoframe is a self-hosted tool that allows simple one-command deployments using Docker.
If you've never heard about it, you can read more here or see it in action here.
And today I'm happy to release Exoframe v5.0 that adds support for simple javascript functions deployments in one command.
Currently, Exoframe supports 4 types of javascript functions:
- HTTP functions - your typical HTTP request handler
- Worker functions - anything that has to run in the background (e.g. bots, repeated tasks, etc)
- Trigger functions - your own triggers that can invoke custom functions
- Custom functions - handlers for your custom triggers
Here's a quick example walkthroughs that demonstrate creation of each type of functions.
Creating HTTP function
First, let's write the function itself.
Exoframe will require
whole function folder so make sure to either call your file index.js
or to include package.json
that points to your main file.
In this case, let's touch index.js
and write the following code in it:
// index.js
module.exports = async (event, context) => {
// use context.log to provide logs to exoframe
// those logs can be then accessed from exoframe CLI
context.log('test log');
context.log('other log');
// you can just return a value
return `hello world`;
// alternatively you can use reply prop
// to directly access Fastify reply object
context.reply.code(200).send('hello world!');
// make sure to return false-y value if you do this
// so exoframe doesn't try to send the response second time
return false;
};
Note the usage of context.log
for logging. Doing so will allow you to get logs from your function using exoframe logs your-function-name
command.
Next, we need to generate new Exoframe config for your function.
To do that, simply execute:
$ exoframe init -f
This will generate a config that looks like this:
{
"name": "test-function",
"function": true
}
By default, Exoframe considers functions to be HTTP functions and will route them to /${config.name}
- so, /test-function
in our case.
This can be changed by editing the config to include route
property, e.g.:
{
"name": "test-function",
"function": {
"route": "test"
}
}
Now you can deploy your function using Exoframe by simply running exoframe deploy
!
Creating worker function
Once again, let's start with the function itself.
Let's touch index.js
and write the following code in it:
// index.js
module.exports = async (_, context) => {
// use context.log to log stuff, just as in HTTP function
context.log('Worker started.');
// worker can execute any long-running task you want
let counter = 0;
setInterval(() => {
context.log(`Worker: ${counter++}`);
}, 1000);
};
After that we want to generate Exoframe config in the same manner as for HTTP function, but then we'll need to modify it to include new type
property, like so:
{
"name": "test-worker",
"function": {
"type": "worker"
}
}
This will tell Exoframe it should start current function in a separate Worker Thread.
And now your worker function is ready for deployment!
Creating trigger function
And again, let's start with the function itself.
Let's touch index.js
and write the following code in it:
module.exports = async (dispatchEvent, context) => {
// log
context.log('Trigger started.');
// in this case we trigger all subscribed functions every 1s
const interval = setInterval(() => {
context.log(`Triggering!`);
// dispatching new events to all function with data
dispatchEvent({data: 'hello world!'});
}, 1000);
// trigger function should return a cleanup function
return () => {
clearInterval(interval);
};
};
Note that your trigger needs to return a cleanup function that, well, does the cleanup once you remove the function from your server.
After that, you'll need to generate a config file and edit it to include type
property set to trigger
, like so:
{
"name": "test-trigger",
"function": {
"type": "trigger"
}
}
That's it, your trigger is ready to be deployed!
Creating custom handler function
Finally, let's see how you can create custom handlers for your triggers.
Let's write that index.js
once again:
module.exports = async (event, context) => {
// Will get custom data from trigger above, so logging will say:
// Custom function triggered: {"data": "hello world!"}
context.log(`Custom function triggered: ${JSON.stringify(event.data)}`);
};
Now we need to tell Exoframe that our current function should react to our custom trigger. This is done by using type
property and assigning a value equal to the name of our custom trigger, like so:
{
"name": "test-triggered-fn",
"function": {
"type": "test-trigger"
}
}
And now you can deploy your custom handler!
That's it!
That covers all the basics with regards to working with functions in Exoframe.
You can find more detailed info in Exoframe docs.
Try it out and let me know what you think!
Top comments (0)