How I discovered faas and what it changed for me

Regularly, I discover myself thinking "wow, that's so simple I can build this in a weekend". My rational brain kicks in at some point: "Waaaaiiit a second, if it's so simple, why am I not seeing this done a million times?". Here I usually start better scoping and either find the answer to my question.

Often, my developer mind insists on "it's actually just two API endpoints and then I could do this and that". And often this holds true for the core functionality. If some basic validation gives a green light for working on it from a commercial perspective, I still need to consider the tech stack and marketing approach, as building alone doesn't do it.

I'm not super fixed on the approach, my main goal is usually to keep long term overhead low. Laravel is my go-to solution for anything backend-heavy, but its power comes at a complexity cost too. For two little API endpoints used in, for example, a browser extension is a bit of an overkill.

Function as a service sounds like a great step towards "just having a few API endpoints". AWS Lambda is the name everyone is having in mind here. But any gains from simplicity are eaten up by AWS complexity. If you are new to AWS (Lambda), it easily takes you double or more time to get it running as you spend building the little lean function in the first place. This doesn't go well with the plan to "just chuck this out over the weekend".

Enter: faasd #

Function as a Service should be easy. Here comes faasd into play. It's a self-hosted alternative to run functions. It allows you to run a simple copy & paste installer script on your machine getting it up and running. It takes less than ten minutes to get to work. It's production-ready and helps to remove the learning curve involved with Kubernetes and co.

faasd is a self-hosted alternative to AWS Lambda to run functions. Production-ready within minutes ⏲️

Once you have deployed your faasd instance, it's a matter of one command to push your function into production. From there it's up to you what you like to build. I catch myself breaking up the structure of larger applications in functions. It builds the container, publishes, and deploys your function code ready-to-use in seconds. To run this you will need the FaaS CLI. Again this is installed in under one minute thanks to copy and paste that just works.

Found a great library but it's written in the "wrong" language? Thanks to the flexibility, you can also jump between programming languages easily. I use a mix of nodejs, PHP, and Python by now.

With functions you libraries aren't in the wrong language anymore.

This helps to truly break up large applications into functional parts using the best tool for you. You can get a rich list of the official templates by running:

$ faas-cli template store list

NAME SOURCE DESCRIPTION
csharp openfaas Classic C# template
dockerfile openfaas Classic Dockerfile template
go openfaas Classic Golang template
java8 openfaas Java 8 template
java11 openfaas Java 11 template
java11-vert-x openfaas Java 11 Vert.x template
node12 openfaas HTTP-based Node 12 template
node openfaas Classic NodeJS 8 template
php7 openfaas Classic PHP 7 template
python openfaas Classic Python 2.7 template
python3 openfaas Classic Python 3.6 template
python3-dlrs intel Deep Learning Reference Stack v0.4 for ML workloads
ruby openfaas Classic Ruby 2.5 template
ruby-http openfaas Ruby 2.4 HTTP template
python27-flask openfaas Python 2.7 Flask template
python3-flask openfaas Python 3.7 Flask template
python3-flask-debian openfaas Python 3.7 Flask template based on Debian
python3-http openfaas Python 3.7 with Flask and HTTP
python3-http-debian openfaas Python 3.7 with Flask and HTTP based on Debian
golang-http openfaas Golang HTTP template
golang-middleware openfaas Golang Middleware template
python3-debian openfaas Python 3 Debian template
powershell-template openfaas-incubator Powershell Core Ubuntu:16.04 template
powershell-http-template openfaas-incubator Powershell Core HTTP Ubuntu:16.04 template
rust booyaa Rust template
crystal tpei Crystal template
csharp-httprequest distantcam C# HTTP template
csharp-kestrel burtonr C# Kestrel HTTP template
vertx-native pmlopes Eclipse Vert.x native image template
swift affix Swift 4.2 Template
lua53 affix Lua 5.3 Template
vala affix Vala Template
vala-http affix Non-Forking Vala Template
quarkus-native pmlopes Quarkus.io native image template
perl-alpine tmiklas Perl language template based on Alpine image
crystal-http koffeinfrei Crystal HTTP template
rust-http openfaas-incubator Rust HTTP template
bash-streaming openfaas-incubator Bash Streaming template
cobol devries COBOL Template

There are also inofficial templates you can find with a bit of research on GitHub.

Start with a new function by running:

faas-cli new function-name --lang node12

This creates a function based on the node12 template. Now you can develop the function in the handler.js-file. This approach works similarly for all other functions. Once you ready run faas-cli up to deploy the function.

Building a Function #

I like to learn by doing. So I started by building a simple function to detect the language of a given string. The whole function including access control is only 31 lines with plenty of space:

'use strict'

const fs = require('fs')
const fsPromises = fs.promises
let franc = require('franc')

module.exports = async (event, context) => {
// Check the auth token
let secret = await fsPromises.readFile("/var/openfaas/secrets/franc-token", "utf8")
let auth = event.headers["authorization"]
if(!auth && auth != "Bearer: " + secret) {
return context
.status(403)
.headers({"Content-Type": "application/json"})
.succeed({"status": "Unauthorized"})
}

let response = {}
if (event.query.query == undefined || event.query.query.length == 0) {
response.status = 'Error'
response.message = 'No query string provided'
} else {
response.status = 'Success'
response.result = franc.all(event.query.query).splice(0, 10)
}

return context
.status(200)
.headers({"Content-Type": "application/json"})
.succeed(response)
}

Functions as a service are made for this: You can easily try out a library or different programming language as it's made to be disposable. Don't like how it's going? Drop it, delete the function and your system is clean once more. No compilers, dependencies, and other tooling remain on your system.

Lessons learned along the way #

At the beginning, I didn't want to run my own container registry. I expected additional overhead and "another thing to maintain". This turned out to be a mistake, as the setup was almost as easy as faasd itself. Plus, the performance is much better than relying on Docker Hub.

I got it up and running on my Hetzner server in a few minutes using some guides from DigitalOcean.

After spinning up your server, the steps break down to:

I should have also paid closer attention to the OpenFaaS workshop at the beginning. It guides you through the basics with examples better than purely self-discovery does. This is especially true for me, as I'm not deep in the serverless space.

Worry about scaling, when you get to scale #

As with any solution approach, there are limitations. For the most time, I leave these concerns out. It simply doesn't matter if my functions can scale to millions of users, as I don't have millions of users. Migrating to a more scalable approach such as OpenFaaS Cloud should be very doable.

Worry about scaling, when you get to scale. Until then build and market.

Community: The People #

We can probably agree: The people behind a project matter to its success for a large part. The OpenFaaS project is maintained and driven by Alex Ellis. Support is mostly done via a Slack channel. You'll be asked to contribute donations to the project as part of this. You should be aware of this in advance, as you might get publicly called out at the most inconvenient time.

Get Playing #

As with any reading: It can only take you so far. Make sure to put a few hours aside and check out faasd! It does come with a little overhead to learn and keep up. Especially for independent developers eyeing to monetize an API or build a small SaaS this could be a great solution.

🙏🙏🙏

Since you've made it this far, sharing this article on your favorite social media network would be highly appreciated 💖! For feedback, please ping me on Twitter.

Published