Backstage Functions
Backstage Functions is an Open Source Serverless Platform able to store and execute code.
Benefits
- Your code will be executed in an isolated environment
- You don't have to worry about infrastructure
- Functions can be called at any time by any project
FAQ
-
Which languages are supported? Currently, only Javascript.
-
Is it based on events? Not yet.
-
How the code execution happens in an isolated way? It uses the Backstage Functions Sandbox.
Running locally without Docker
Requirements
- Redis 3.0+
- NodeJS 6.10.2
Download the project
git clone https://github.com/backstage/functions.git
Setup
make setup
Run
make run
Running locally via Docker
Requirements
- Docker 1.12+
- Docker compose 1.8+
Download docker-compose.yml
mkdir functions
cd functions
curl 'https://raw.githubusercontent.com/backstage/functions/master/docker-compose.yml' > docker-compose.yml
Run
docker-compose up
How to use
Creating a function
Your function will have a file, which you define any name you want, and it has to have a function called main
, with two parameters: req
and res
. Req represents the Request
and Res represents the Response
.
At the end of your code, you'll have to use the send
method.
Example of a function
function main(req, res) {
const name = (req.body && req.body.name) || "World"
res.send({ say: `Hello ${name}!` })
}
To store your function, you can make a POST
request to /functions/:namespace/:name
:
curl -i -X POST http://localhost:8100/functions/example/hello-world \
-H 'content-type: application/json' \
-d '{"code":"function main(req, res) {\n const name = (req.body && req.body.name) || \"World\"\n res.send({ say: `Hello ${name}!` })\n}\n"}'
ps: if already exists, it will not be updated
Updating a function
To update your function, you can make a PUT
request to /functions/:namespace/:name
:
curl -i -X PUT http://localhost:8100/functions/example/hello-world \
-H 'content-type: application/json' \
-d '{"code":"function main(req, res) {\n const name = (req.body && req.body.name) || \"World\"\n res.send({ say: `Hello ${name}! Nice meeting you...` })\n}\n"}'
ps: if it doesn't exists, it will be created
Deleting a function
To delete your function, you can make a DELETE
request to /functions/:namespace/:name
:
curl -i -X DELETE http://localhost:8100/functions/example/hello-world \
-H 'content-type: application/json'
Executing a function
To execute a function, you can make a PUT
request to /functions/:namespace/:name/run
:
curl -i -X PUT http://localhost:8100/functions/example/hello-world/run \
-H 'content-type: application/json'
The result will be something like:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Length: 22
ETag: W/"16-soBGetwJPBLt8CqWpBQu+A"
Date: Tue, 11 Oct 2016 16:51:04 GMT
Connection: keep-alive
{"say":"Hello World!"}
If one needs to pass an object in the request, the payload is executed:
curl -i -X PUT http://localhost:8100/functions/example/hello-world/run \
-H 'content-type: application/json' \
-d '{"name": "Pedro"}'
The result will be something like:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Length: 22
ETag: W/"16-Ino2/umXaZ3xVEhoqyS8aA"
Date: Tue, 11 Oct 2016 17:13:11 GMT
Connection: keep-alive
{"say":"Hello Pedro!"}
Executing functions in a pipeline
To execute many functions in a pipeline, you can make a PUT
request to /functions/pipeline
:
// Function0
function main(req, res) {\
res.send({x: req.body.x * 10});
}
// Function1
function main(req, res) {
res.send({x: req.body.x * 20});
}
curl -g -i -X PUT 'http://localhost:8100/functions/pipeline?steps[0]=namespace/function0&steps[1]=namespace/function1' \
-H 'content-type: application/json'
-d '{"x": 1}'
Considering the curl above, the pipeline result would be like this:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Length: 22
ETag: W/"16-Ino2/umXaZ3xVEhoqyS8aA"
Date: Tue, 11 Oct 2016 17:13:11 GMT
Connection: keep-alive
{"x": 200}