https://github.com/ccfontes/faas-bb
An OpenFaaS template for writing Functions in Babashka.
https://github.com/ccfontes/faas-bb
babashka bb clojure openfaas
Last synced: about 2 months ago
JSON representation
An OpenFaaS template for writing Functions in Babashka.
- Host: GitHub
- URL: https://github.com/ccfontes/faas-bb
- Owner: ccfontes
- License: mit
- Created: 2023-04-11T20:08:52.000Z (about 3 years ago)
- Default Branch: main
- Last Pushed: 2024-05-21T09:54:23.000Z (about 2 years ago)
- Last Synced: 2025-10-20T04:02:34.723Z (8 months ago)
- Topics: babashka, bb, clojure, openfaas
- Language: Clojure
- Homepage:
- Size: 73.2 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.adoc
- License: LICENSE
- Security: SECURITY.md
Awesome Lists containing this project
README
:url-proj: https://github.com/ccfontes/faas-bb
:img-ci-tests-status: {url-proj}/actions/workflows/faas_fn_build_invoke.yml/badge.svg
:img-ci-hadolint-status: {url-proj}/actions/workflows/hadolint.yml/badge.svg
:img-ci-clj-kondo-status: {url-proj}/actions/workflows/clj-kondo.yml/badge.svg
:url-ci-status-tests: "{url-proj}/actions/workflows/faas_fn_build_invoke.yml"
:url-ci-status-hadolint: "{url-proj}/actions/workflows/hadolint.yml"
:url-ci-status-clj-kondo: "{url-proj}/actions/workflows/clj-kondo.yml"
:img-license: https://img.shields.io/badge/license-MIT-black.svg
= faas-bb image:{img-ci-tests-status}[link={url-ci-status-tests}] image:{img-ci-hadolint-status}[link={url-ci-status-hadolint}] image:{img-ci-clj-kondo-status}[link={url-ci-status-clj-kondo}] image:{img-license}[link=LICENSE]
An https://github.com/openfaas[OpenFaaS] template for writing Functions in https://babashka.org[Babashka] (v1.3.187 SNAPSHOT).
== Why
> The ergonomics of Babashka, combined with the simplicity of Clojure, make it a great choice for writing Functions in OpenFaaS, from single purpose Functions, to frontend facing REST APIs, to serving hiccup backed HTML pages - delivered with a back-to-back joyful development experience.
Babashka is designed for minimal memory usage, allowing you to scale up your narrow-purposed Functions with comparable RAM consumption.
Babashka scripts run immediately, ensuring:
* that Function cold start times are kept to a minimum.
* a rapid development feedback loop.
* a simple REPL workflow - just start everything all over again, it's fast.
== Prerequisites
* https://docs.openfaas.com/cli/install/[OpenFaaS CLI]: makes the `faas-cli` command available.
*Optional for REPL support*
* https://github.com/babashka/babashka#installation[Babashka]: makes the `bb` command available.
* rlwrap: readline support, here for Babashka REPL.
== Usage
=== Pull OpenFaaS template
To create Babashka Functions with this template, use the following command *once*:
[source, bash]
----
faas-cli template pull https://github.com/ccfontes/faas-bb
----
If you ever need to update the template, simply run the command above with the `--overwrite` flag.
=== Create a Babashka Function
Create Babashka Functions as with the following command example:
[source, bash]
----
faas-cli new --lang bb my-bb-function
----
A new project is created for a function defined as `my-bb-function`. It will contain:
* a `handler` namespace that is required for the template to work properly. This namespace needs to have a top-level `handler` function with 0 or 1 arguments.
* a `bb.edn` file where ship dependencies can be added. Remove this file if you don't need to add any dependencies or run a REPL without passing the classpath explicitly.
* a `test` directory containing:
** `run_tests.clj` with the namespace that will be used to run the tests. You can use any test library and test runner you like.
** a `bb.edn` file where test dependencies can be added. Remove this file if you don't need to add any dependencies.
=== Defining Function handler
In `bb` language:
[source, clojure]
----
(defn handler [{:keys [headers body context] :as event}]
...)
----
`event` is a map containing `:headers`, `:body` and `:context` keys.
`:headers` contains headers, as such:
[source, clojure]
----
{:content-type "application/json"}
----
`:body` is the payload body. When passing a JSON object payload and using `bb` language, the payload will be automatically parsed as a Clojure map with keyword keys. There are cases where it's preferable to have string keys in the payload body, and it's possible to support them by setting `keywords: false` in the Function in `stack.yml`:
[source, yml]
----
my-function:
lang: bb
handler: ./anything/my-function
image: ${DOCKER_REGISTRY_IMG_ORG_PATH}/my-function
environment:
keywords: false
----
`:context` contains environment variables. Additional environment variables can be defined in the `stack.yml` file, as such:
[source, yml]
----
my-function:
lang: bb
handler: ./anything/my-function
image: ${DOCKER_REGISTRY_IMG_ORG_PATH}/my-function
environment:
MY_ENV1: foo
MY_ENV2: 2
----
`:context` will contain:
[source, clojure]
----
{:my-env1 "foo"
:my-env2 2}
----
If you declare secrets in the `stack.yml` file, these will be available in `:context` map as well. Let's start with an example:
[source, yml]
----
my-function:
lang: bb
handler: ./anything/my-function
image: ${DOCKER_REGISTRY_IMG_ORG_PATH}/my-function
secrets:
- foo
- baz
----
A secret value that is an EDN string, when internally parsed as a Clojure map, will have its content spliced into the `:context` map. Otherwise, the secret will be available in the `:context` map as `{:secret-name }`, with `` parsed as a Clojure data structure other than a map.
Following up from the definition of `my-function` above, we define the following secrets:
[source, bash]
----
echo 'bar' | faas-cli secret create foo
echo '{:spam "eggs"}' | faas-cli secret create baz
----
becomes this in the `:context` map:
[source, clojure]
----
{:foo "bar" :spam "eggs"}
----
=== Function tests
Tests for your Function run when you build the Function image (`faas-cli build`).
A `test` directory in the Function's top-level directory is provided, containing:
* `run_tests.clj`, with the namespace that will be used to run the tests. You can use any test library and test runner you like.
* a `bb.edn` file where test dependencies can be added. Remove this file if you don't need to add any dependencies.
To disable running existing tests, set the `TEST` build time argument to `false`:
[source, yml]
----
my-function:
lang: bb
handler: ./anything/my-function
image: ${DOCKER_REGISTRY_IMG_ORG_PATH}/my-function
build_args:
TEST: false
----
If you don't plan on testing, you can remove the `test` directory altogether.
Existing test files are removed from the final Docker image used to run the Function in OpenFaaS.
=== Spin up a REPL
Spin up a REPL in the context of your Function project.
NOTE: You'll need to have https://github.com/babashka/babashka#installation[Babashka installed] in your local.
In the root directory of your Function run:
[source, bash]
----
rlwrap bb
----
Spins up a REPL with readline support.
If you remove `bb.edn` with just `{:paths ["."]}` in it, the Function will still work, but then you will need to explicitly pass the classpath when spinning up a REPL:
[source, bash]
----
rlwrap bb -cp .
----
== link:examples[Function examples]
See the link:examples[examples] directory to find a fully working set of OpenFaaS Functions written in Babashka.
== faas-bb tests
=== CI tests
All tests run in CI with Github Actions. Some commands link:.github/workflows/faas_fn_build_invoke.yml[can be found in a Github Actions workflow] to help you with testing your changes before pushing them to a topic branch.
=== Unit tests
Run locally the unit tests for the `bb` template.
The requirement is that babashka (`bb`) is https://github.com/babashka/babashka#installation[installed].
[source, bash]
----
cd template/bb
bb --config tests.edn tests.clj
----
`tests.clj` is included with the template so you can test any changes you make to the template before using it.
== Projects using faas-bb
- https://www.mailbriefly.com[MailBriefly.com] is using `faas-bb` on all its microservices (with joy).
== Contributing
Contributions are welcome! If you find a bug or have an idea for a new feature, please open an issue or submit a pull request.
The template may benefit from some common middleware functions, such as those offered in the https://github.com/ring-clojure/ring-defaults/blob/master/src/ring/middleware/defaults.clj[ring-defaults library]. Users are welcome to recommend integrating any middleware they think would be useful for handling common web application needs.
== Third party code
The following files are derived from https://github.com/ring-clojure[ring] to work with Babashka, originally authored by James Reeves and contributors, and used under the MIT license: link:template/bb/lib/ring/middleware/json.clj[ring.middleware.json], link:template/bb/lib/ring/util/io.clj[ring.util.io], link:template/bb/lib/ring/util/mime_type.clj[ring.util.mime-type], link:template/bb/lib/ring/util/parsing.clj[ring.util.parsing], link:template/bb/lib/ring/util/response.clj[ring.util.response], link:template/bb/lib/ring/util/time.clj[ring.util.time].
== link:LICENSE[License]
Copyright (c) 2023 Carlos da Cunha Fontes.
This project is licensed under the MIT License. See link:LICENSE[LICENSE] for details.