Cloud Functions in Go
It’s happened! Go is now an officially supported language for Google Cloud Functions (check the blog). Goodbye node.js… for me at least.
Let’s take it for a quick spin with a quick function that uses some shared code to output some JSON.
All of the code for this project at https://github.com/theyakka/go-func-example.
The Code
Let’s create the directory structure first. We will need two folders: one for our common code and one for our functions code. The overall structure will look like this:
+ myfunctions
- common
- functions
To allow our functions to see / use the common code, we’re going to create a local module using the module functionality added in go 1.11. So, under both the common
and the functions
folders, let’s first create a couple ofgo.mod
files.
For simplicity, we’re going to use the module name mysite.com/myfunctions
as the base identifier for all of our code. Therefore, the contents of the common/go.mod
file should be module mysite.com/myfunctions/common
and that’s it.
The functions go.mod
is a little more complicated. Here is what it looks like:
Quick breakdown of what is going on here. Using the version number v0.0.0
tells Go that we’re going to be working outside of a VCS system so it shouldn’t try to hit mysite.com/myfunctions/common
to check for the latest version and download it. However, we still need to tell Go where to find it, so that’s what we achieve with the replace
line. The replace
tells Go that it should go to the common folder for the common code. A bit verbose, but it works.
Next, lets set up our first function entry point. Under the functions
folder, create a file called message_func.go
. Now we need to add a function handler. Let’s call ours OuputMessage
:
Now, just for the sake of an example of accessing some common code from our function, let’s add a helper struct
that we can pass a message to and it generates & writes a JSON response to our ResponseWriter
.
Create a file called json_message_writer.go
in a folder called writers
under the common
module. Now, let’s add some quick and dirty code to produce and write the JSON. The file should look like:
All that we’re doing here is simply taking a string value that is passed into the JSONMessageWriter
at creation time, wrapping it in a simple response structure and encoding the map to a JSON string. Pretty simple.
So, now we can update our original function to use the message writer.
To make it a bit more dynamic, we’re pulling the message we’re going to display from the a query string value (called message
) and passing that along to our JSONMessageWriter
. If there is an error, we’re returning a 500 status code and printing the error to the console/log and writing it as plain text to the ResponseWriter
. We would obviously want to make that JSON also but, for now, we’re not going to deal with that.
And that should do it for the code for the moment. Let’s give it a quick test and then move onto deployment.
Testing Locally
To test our function locally we can use a test (which we should be writing anyway). Let’s set up a quick test to test that the function executes correctly (returns a status code 200) and matches the JSON generated by the JSONMessageWriter
:
Run the test from your chosen IDE or using the command line (inside the functions
directory):
go test -run TestOutputMessage
You should see a PASS like:
PASS
ok mysite.com/myfunctions 0.003s
This means we’re now good to move onto deployment!
Deployment
I’m not going to go over all of the instructions on setting up the gcloud command line tool, linking your project, authorizing, etc. It’s well documented here. So, I’m going to assume you made a coffee (or opened a cold beer) and ran through those steps already.
Before you jump in too quickly trying to deploy your function, we need to do one quick thing. We need to tell the gcloud tool to ignore our go.mod
and go.sum
files as we’re going to use the module vendoring function to connect our modules.
To do this we first create a file called .gcloudignore
under the functions
directory with the following contents:
go.mod
go.sum
That’s it. It’ll now ignore those files when it tries to deploy our app. Ok, as I mentioned just a moment ago, we also need to vendor our app. To do that, we run:
go mod vendor
This will pull in our common module into our functions module (under a new vendor
directory). Go will look in the vendor directory by default when trying to resolve imports, so we should be all good.
We can now deploy our function!
Run:
gcloud functions deploy OutputMessage --runtime go111 --trigger-http
This command deploys our OutputMessage
function to the current project as a HTTP function and tells it we want to use the Go 1.11 runtime. It should take 10 — 60seconds for it to deploy (especially if it’s the first time), but after that you will see a bunch of information about the deployment in your console. One of the values printed out will be httpsTrigger
. This will be the URL of your new cloud function. Let’s hit that URL.
Open a browser window/tab and enter the httpsTrigger
URL with the query string ?message=Hello World
appended to the end of your URL. You should see the following JSON output:
{
"data": {
"message": "Hello world"
}
}
If all has gone well you’re now up and running on Google Cloud Functions with Go 1.11!
If you have any issues, try retracing your steps and check out the docs as it’s likely you have missed a configuration step somewhere.
Good luck and have fun writing Functions!
As a quick reminder, all of the code can be found at https://github.com/theyakka/go-func-example.
About Yakka
Yakka is a digital product design and development agency. Whether it’s the web, Flutter, native mobile apps or a back-end project, we’re the ones to get it done for you.
Reach out today!