Writing OpenFaas Serverless Functions in Go

Prelude

In this post I will take you through the process of writing a Serverless function in Go with OpenFaas.

Note: Knowledge of Linux and Go will be very helpful.

Getting Started

Before we get to writing Serverless functions in Go, you need to have a OpenFaas deployment. If you do, great, you can skip to the next section. If you don’t, then you can follow Alex’s (founder of OpenFaas) tutorials on how to get a deployment up and running. He has a lot of great tutorials and posts that have heavily influenced the creation of this post. You should also check out his post on creating Go Serverless functions as well as he goes much more in depth.

Writing a Serverless function

Note: I will be developing the following function on a raspberry pi. This should not matter though as long as you can run the OpenFaas CLI and build and deploy Docker containers.

The following function that we are going to create will simply return the current time on the machine that executes the function.

First create the function project.

faas-cli new --lang=go-armhf get-time
Note: As I am running Go on ARM architecture the following suffix '-armhf' was added to the '--lang' parameter. This is not required if you are developing and building Go on x86.

What that command above should have done is create 3 seperate items;

  • template folder which holds all the templates required to build and run Serverless functions with your chosen language in OpenFaas.
  • A get-time.yml file that holds the configuration of your function. For example, the name of your function as a docker image, where the function will deploy to and the location of your function handler (the actual code of your function).
  • A get-time folder that will hold your function code.

If you have those three we can open up the handler.go file in the get-time folder. You should see the following:

package function

import (
	"fmt"
)

// Handle a serverless request
func Handle(req []byte) string {
	return fmt.Sprintf("Hello, Go. You said: %s", string(req))
}

First we want to import the time package so that we can get the current time.

import (
        "fmt"
        "time"
)

Now we can change the return message with the current time.

return fmt.Sprintf("The current time on this machine is %s", time.Now())

Before we can build, push and deploy our changes we need to make sure that out get-time.yml file has the correct configuration. The following is an example of my get-time.yml file. I have highlighted the changes that I had made in mine.

provider:
    name: faas
    gateway: http://192.168.1.125:31112

functions:
    get-time:
        lang: go-armhf
        handler: ./get-time
        image: marcussmallman/get-time

Next, we can build this function and deploy it to OpenFaas.

faas-cli build -f get-time.yml

faas-cli push -f get-time.yml

faas-cli deploy -f get-time.yml

If the 3 commands above were successful then we can head over to the OpenFaas UI and expect to see the get-time function there.

Now we can press the Invoke button which will call our function that we just created and hopefully return the current time.

And there we have it.

To End

As simple as this post was to follow, I think it is a great example of how powerful and practical Serverless functions can be. The fact that a function is what scales depending on load is just awesome and potentially very beneficial. That’s not to say it’s an answer to all problems, but I think it is definitely an exciting new technology that we should all be aware of.

– Marcus

3 thoughts on “Writing OpenFaas Serverless Functions in Go”

  1. hi i am getting error when i change to my docker hub image ERROR – Could not execute command: [docker build -t nsrushi/show-time:latest .]

    1. Hi Rushi,

      I believe I have managed to reproduce the error on Docker for Windows.
      If I am correct in stating that the Dockerfile fails at Step 5 outputting the following:

      Run “gofmt -s -w” on your Golang code

      ERROR – Could not execute command: [docker build -t nsrushi/show-time:latest .]

      Then a current work-a-round would be to execute the command stated: gofmt -s -w on all of the .go files in your function, INCLUDING the main.go file in the template folder located at /template/go or if you are building for Raspberry Pi then /template/go-armhf.

      Example:
      gofmt -s -w function-name/handler.go
      gofmt -s -w template/go/main.go

      This does require you to have go installed.

      I hope this helps!

      Update: Looks like it all comes down to line endings (LF/CRLF). When developing your function on a Windows machine you need to make sure that the EoL style remains LF. The most common culprit that changes the line endings is Git. There is a command that can be executed git config --global core.autocrlf false which will stop changing the EoL style.

      1. thanks but it still getting errors. Do you have time tomorrow. let me know or email my “ns.rushi@gmail..com” or provide your email and i will send you MR.

Leave a Reply

%d