Digital Ocean Functions Quick Start

Functions as a service have been around for a while now. They can be used to quickly create new functionality, and as they only run when the function is called can be a pretty economical way of using compute resources in a cloud environment.

Digital Ocean is a cloud provider focussing on providing simple, cost-effective hosting services. One of their offerings is Functions. It’s a serverless platform enabling developers to deploy code quickly and easily.

We’re going to take a quick trip through how to get up and running with Digital Ocean Functions in the quickest time possible.

The code for this example is available here - https://github.com/crzyuk/do-functions-example

Setting things up

Digital Ocean have a really handy CLI tool called doctl. It lets you interact with all their services and is pretty easy to use.

Head over to https://docs.digitalocean.com/reference/doctl/ and use the instructions there to install it on your system.

Once this is complete, you’ll need to install the serverless functions

$ doctl serverless install

This should give you a working doctl setup and we can continue on.

Functions exist in a namespace within Digital Ocean. If you haven’t created on already, we’ll need to do that now.

$ doctl serverless namespaces create --label "test-namespace" --region "lon1"
Connected to functions namespace 'fn-xxxx.....' on API host 'https://faas-lon1-xxxxxxx.doserverless.co'

This just ringfences difference resources into one place within the platform.

Docs link

Creating a Function

A function consists of an application, and some other parameters to describe how it should be run.

Currently Digital Ocean Functions can run using the following languages

  • Go 1.17

  • Go 1.20

  • Node.js 14

  • Node.js 18

  • PHP 8.0

  • PHP 8.2

  • Python 3.9

  • Python 3.11


The doctl cli also helps when starting a new function.

$ doctl serverless init --language go crzy

This will give you a new folder with the correct files available to start developing straight away!

The folder should look something like this.

crzy/
├── packages
│   └── sample
│       └── hello
│           └── hello.go
└── project.yml

Using Go to write Functions

There are a few things we have to keep in mind when writing Go for use with Digital Ocean Functions

1) The application needs to have a Main function - note the captial M

2) The Main function can have up to 2 arguments.

  • A context.Context variable

  • An Event variable

The Event variable allows you to pass custom parameters to the Function as well as giving some of the usual parameters available for an HTTP request.

The event takes on the form of the following JSON.

{
  "http": {
    "headers": {
      "accept": "*/*",
      "accept-encoding": "gzip",
      "user-agent": "Go",
      "x-forwarded-for": "123.123.123.123",
      "x-forwarded-proto": "https",
      "x-request-id": "xxxxxxxxxxxx"
    },
    "method": "POST",
    "path": "/"
  },
  "name": "world"
}

The event can be unmarshalled to anything that the JSON package in the standard library can unmarshal to. This gives quite a bit of flexibility to what your function can receive, and what types you can use. For instance if you unmarshal to a map[string]string, you would have simple access to the parameters provided in the request.

The following is a simple application that reads from the request and writes to the response.

package main

func Main(args map[string]interface{}) map[string]interface{} {
	name, ok := args["name"].(string)
	if !ok {
		name = "world"
	}
	msg := make(map[string]interface{})
	msg["body"] = "Hello " + name + "!"
	return msg
}

Note that we’re not actually using any imports here, it’s possible to use extremely simple code to create things in Go that will work in Functions.

The returned variable is similar in function to the input Event variable - anything that can be Marshalled to JSON by Go can be used.

Deploying the function

Now we have all the bits to actually make something work!

Using doctl again we can deploy the function to Digital Ocean and give it a test.

$ doctl serverless deploy .
.......

$ doctl serverless fn invoke crzy/hello
{
  "body": "Hello world!"
}

Looking back at our folder structure above we see that there’s a project level folder named crzy, and a sub folder named hello. We use those facts in the invoke command, and the output we see is the JSON of the map we created.

Hopefully this has been a quick intro to functions in the Digital Ocean environment and how quick and easy it is to get them running with Go.

This is all documented well in the Digital Ocean docs that can be found here.

Next
Next

Setting up Terraform