HTTP Google Cloud Functions in Go

Join Sign in

HTTP Google Cloud Functions in Go

45 minutes 1 Credit


Google Cloud self-paced labs logo


Go is an open source programming language that makes it easy to build simple, reliable, and efficient software. Go is already installed when using Cloud Shell.

Cloud Functions is an event-driven serverless compute platform. Cloud Functions allows you to write your code without worrying about provisioning resources or scaling to handle changing requirements.

There are two types of Cloud Functions:

  • HTTP functions respond to HTTP requests. You'll build one in this lab.
  • Background functions are triggered by events, like a message being published to Cloud Pub/Sub or a file being uploaded to Cloud Storage. This address this in this lab, but you can read more in the documentation.

Cloud functions architecture diagram

In this lab you will create your own Google Cloud Function in Go.

Note: This lab is intended for people who are somewhat familiar with Go and want to learn about Cloud Functions. There are explanations for all of the Go code, but may not explain everything needed for someone completely new to Go. There is no assumed knowledge about Cloud Functions.

What you will build

In this lab, you will publish a Cloud Function that, when invoked via HTTP, will display an image of the Go gopher, designed by Renee French.

The GO gopher mascot

What you will learn

  • How to write an HTTP Cloud Function in Go.
  • How to test an HTTP Cloud Function in Go.
  • How to run a local Go HTTP server to try the function.

Setup and requirements

Before you click the Start Lab button

Read these instructions. Labs are timed and you cannot pause them. The timer, which starts when you click Start Lab, shows how long Google Cloud resources will be made available to you.

This hands-on lab lets you do the lab activities yourself in a real cloud environment, not in a simulation or demo environment. It does so by giving you new, temporary credentials that you use to sign in and access Google Cloud for the duration of the lab.

To complete this lab, you need:

  • Access to a standard internet browser (Chrome browser recommended).
Note: Use an Incognito or private browser window to run this lab. This prevents any conflicts between your personal account and the Student account, which may cause extra charges incurred to your personal account.
  • Time to complete the lab---remember, once you start, you cannot pause a lab.
Note: If you already have your own personal Google Cloud account or project, do not use it for this lab to avoid extra charges to your account.

How to start your lab and sign in to the Google Cloud console

  1. Click the Start Lab button. If you need to pay for the lab, a pop-up opens for you to select your payment method. On the left is the Lab Details panel with the following:

    • The Open Google Cloud console button
    • Time remaining
    • The temporary credentials that you must use for this lab
    • Other information, if needed, to step through this lab
  2. Click Open Google Cloud console (or right-click and select Open Link in Incognito Window if you are running the Chrome browser).

    The lab spins up resources, and then opens another tab that shows the Sign in page.

    Tip: Arrange the tabs in separate windows, side-by-side.

    Note: If you see the Choose an account dialog, click Use Another Account.
  3. If necessary, copy the Username below and paste it into the Sign in dialog.

    {{{user_0.username | "Username"}}}

    You can also find the Username in the Lab Details panel.

  4. Click Next.

  5. Copy the Password below and paste it into the Welcome dialog.

    {{{user_0.password | "Password"}}}

    You can also find the Password in the Lab Details panel.

  6. Click Next.

    Important: You must use the credentials the lab provides you. Do not use your Google Cloud account credentials. Note: Using your own Google Cloud account for this lab may incur extra charges.
  7. Click through the subsequent pages:

    • Accept the terms and conditions.
    • Do not add recovery options or two-factor authentication (because this is a temporary account).
    • Do not sign up for free trials.

After a few moments, the Google Cloud console opens in this tab.

Note: To view a menu with a list of Google Cloud products and services, click the Navigation menu at the top-left. Navigation menu icon

Activate Cloud Shell

Cloud Shell is a virtual machine that is loaded with development tools. It offers a persistent 5GB home directory and runs on the Google Cloud. Cloud Shell provides command-line access to your Google Cloud resources.

  1. Click Activate Cloud Shell Activate Cloud Shell icon at the top of the Google Cloud console.

When you are connected, you are already authenticated, and the project is set to your Project_ID, . The output contains a line that declares the Project_ID for this session:

Your Cloud Platform project in this session is set to {{{project_0.project_id | "PROJECT_ID"}}}

gcloud is the command-line tool for Google Cloud. It comes pre-installed on Cloud Shell and supports tab-completion.

  1. (Optional) You can list the active account name with this command:
gcloud auth list
  1. Click Authorize.


ACTIVE: * ACCOUNT: {{{user_0.username | "ACCOUNT"}}} To set the active account, run: $ gcloud config set account `ACCOUNT`
  1. (Optional) You can list the project ID with this command:
gcloud config list project


[core] project = {{{project_0.project_id | "PROJECT_ID"}}} Note: For full documentation of gcloud, in Google Cloud, refer to the gcloud CLI overview guide.

Set your region and zone

Certain Compute Engine resources live in regions and zones. A region is a specific geographical location where you can run your resources. Each region has one or more zones.

Run the following gcloud commands in Cloud Console to set the default region and zone for your lab:

gcloud config set compute/zone "{{{project_0.default_zone|ZONE}}}" export ZONE=$(gcloud config get compute/zone) gcloud config set compute/region "{{{project_0.default_region|REGION}}}" export REGION=$(gcloud config get compute/region)

Ensure the Cloud Functions API is enabled

  • Run the following command from Cloud Shell to make sure the Cloud Functions API is enabled. This will make sure you can deploy Cloud Functions later in the lab.
gcloud services enable

Download and setup the code

  1. From the Cloud Shell terminal, use curl to download a zip with the code for this lab:
curl -LO
  1. Use unzip to unpack the code. This unpacks a directory (golang-samples-main), which contains sample Go code for
  1. Change to the directory containing the code for this lab:
cd golang-samples-main/functions/codelabs/gopher

The gopher directory contains the following directories and files:

$ tree . ├── cmd │ └── main.go # Binary to run the function locally. ├── go.mod # Go module definition. ├── gophercolor.png # The gopher! ├── gopher.go # Go file with the function. └── gopher_test.go # Go test file.

Task 1. Introducing HTTP Cloud Functions in Go

HTTP Cloud Functions in Go are written as http.HandlerFunc functions, which is an interface defined in the Go standard library. The function must:

  • Be exported, meaning it can be used from another package, which is indicated by the name starting with an uppercase letter.
  • Match the http.HandlerFunc type, meaning the function is of the form func(http.ResponseWriter, *http.Request). (See the Writing Web Applications tutorial for an in-depth guide to writing a full web application in Go.)

For example, here is a "Hello, world" function:

package gopher import ( "fmt" "net/http" ) // HelloWorld prints "Hello, world." func HelloWorld(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, "Hello, world.") } Note: You can open this file in Cloud Shell Editor (click the pencil icon at the top right of Cloud Shell) then using the file tree on the left side of the editor to open the file, golang-samples-main/functions/codelabs/gopher/hello.go.

Deploy this function as an HTTP Cloud Function

  1. From the functions/codelabs/gopher directory you can deploy the function name with gcloud functions deploy:
gcloud functions deploy HelloWorld --runtime go120 --trigger-http --region {{{project_0.default_region | REGION}}}
  1. Enter Y when asked to allow unauthenticated invocations of new function.

This will take a minute or two.


Deploying function (may take a while - up to 2 minutes)...done. availableMemoryMb: 256 entryPoint: HelloWorld httpsTrigger: url: ...

Click Check my progress to verify the objective. Create HelloWorld HTTP Cloud Function

Note: Did you get an error during deployment? Check:

  • Is the Cloud Functions API enabled? If not, there will be an error with a link allowing you to enable it. Otherwise, you can enable it with the command gcloud services enable
  • Be sure your working directory (where you're running gcloud from) is the directory with the .go file in it. You can change directories using cd golang-samples/functions/codelabs/gopher.
  • Is the function name correct? It should be HelloWorld, the name of the Go function you're trying to deploy.
  1. Copy the httpsTrigger URL that's displayed in the output. It will have a form like this:
  1. To test the HelloWorld function, curl into the URL from the last output:
curl https://<REGION>-$


Hello, world.

You've written and deployed a HTTP Cloud Function!

Task 2. Writing the Gopher HTTP Cloud Function

Now make the "Hello, world" function a bit more entertaining by printing an image of a Gopher for every request.

The Go gopher mascot

The following block shows the code to make it happen. You can see this code in Cloud Shell at golang-samples-master/functions/codelabs/gopher/gopher.go.

// Package gopher contains an HTTP function that shows a gopher. package gopher import ( "fmt" "io" "net/http" "os" ) // Gopher prints a gopher. func Gopher(w http.ResponseWriter, r *http.Request) { // Read the gopher image file. f, err := os.Open("gophercolor.png") if err != nil { http.Error(w, fmt.Sprintf("Error reading file: %v", err), http.StatusInternalServerError) return } defer f.Close() // Write the gopher image to the response writer. if _, err := io.Copy(w, f); err != nil { http.Error(w, fmt.Sprintf("Error writing response: %v", err), http.StatusInternalServerError) } w.Header().Add("Content-Type", "image/png") }
  • The file starts with a package declaration and comment. All Go code is written inside a package, with a declaration like this at the top.

  • The import block contains a list of other packages that this file depends on. These packages are referred to in the rest of the file using their name. For example, to use the ResponseWriter type from the http package, you write http.ResponseWriter.

  • Next is the Gopher function declaration.

  • The function starts by reading the gophercolor.png file (see the sample code) using the os.Open function.

  • Then, it checks whether there was an error reading the file, which might occur if the file is corrupted or was accidentally left out of the upload.

  • It uses io.Copy to copy the gopher image to w, the http.ResponseWriter argument. Everything written to w will be sent in the HTTP response.

  • If there was no error when writing the response, the function returns normally.

  1. Deploy this function as you did the "Hello, world" function from before, using gcloud functions deploy and the name of the function, Gopher:
gcloud functions deploy Gopher --runtime go120 --trigger-http --region {{{project_0.default_region | REGION}}}
  1. Enter Y when asked to allow unauthenticated invocations of new function.

  2. To test the function, visit the function's URL in the output from the last command. If everything is working correctly, you will see the gopher in your browser!

The next step is to add a test to make sure your function continues to work.

Click Check my progress to verify the objective. Create Gopher HTTP Cloud Function

Task 3. Writing a test

HTTP Cloud Functions in Go are tested using the testing and httptest packages from the standard library. There is no need to run an emulator or other simulation to test your function—just normal Go code.

Here is what a test looks like for the Gopher function:

package gopher import ( "net/http" "net/http/httptest" "testing" ) func TestGopher(t *testing.T) { rr := httptest.NewRecorder() req := httptest.NewRequest("GET", "/", nil) Gopher(rr, req) if rr.Result().StatusCode != http.StatusOK { t.Errorf("Gopher StatusCode = %v, want %v", rr.Result().StatusCode, http.StatusOK) } }
  • Go tests are written the same way as other Go files. They start with a package declaration and set of imports.
  • The test declaration is of the form func MyTest(t *testing.T). It must be exported and take one argument of type *testing.T.
  • The test creates test response and request values using the httptest package.
  • It calls the Gopher function.
  • After invoking the Gopher function, the test checks the HTTP response code to be sure there were no errors.
  1. To run these tests locally, cd to the directory with the files you're testing:
cd ~/golang-samples-main/functions/codelabs/gopher
  1. In the golang-samples-main/functions/codelabs/gopher directory, use the go test command:
go test -v


=== RUN TestGopher --- PASS: TestGopher (0.00s) PASS ok 0.037s Note: Test not passing?

  • Check the error message for anything helpful.
  • Are you in the same directory as the gopher.go and gopher_test.go files (golang-samples-main/functions/codelabs/gopher)?

Next, you'll create a binary (package main, in Go) so that you can run your function locally and try it in a browser.

Task 4. Running the function locally

To run an HTTP function locally, create an HTTP server and register your function as a handler. (See the Writing Web Applications tutorial for an in-depth guide to writing a full web application in Go.)

You can write an HTTP server for your function in a subdirectory of your function.

Following a Go convention, you name that directory cmd and create a main.go file inside it:

// The cmd command starts an HTTP server. package main import ( "fmt" "log" "net/http" "" ) func main() { http.HandleFunc("/", gopher.Gopher) fmt.Println("Listening on localhost:8080") log.Fatal(http.ListenAndServe(":8080", nil)) }
  • This file uses package main as the package. A main package will be built as a binary that you can run.
  • This file imports, based on the module line of the go.mod next to your function file. When you're writing your own functions, you can name the module whatever you prefer.
  • The func main() is the entry point for the binary. It registers the gopher.Gopher function as an HTTP handler then starts the server using http.ListenAndServe.
  1. To build and run this binary locally, run the following commands:
GO120MODULES=on # Turn on Go modules. go build -o start ./cmd ./start


Listening on localhost:8080
  1. Because the function loads the gophercolor.png image from the current working directory, you have to start your binary from the same directory as the gophercolor.png file. The -o start flag says to name the output binary start. The ./cmd says to build the binary located in the cmd directory.

  2. Now use the Cloud Shell Web Preview to test the server in your browser.

  • Click the Web Preview button The web preview icon.
  • Select port 8080 from the displayed menu.

Cloud Shell opens the preview URL on its proxy service in a new browser window. The web preview restricts access over HTTPS to your user account only.

If everything is working properly, you should see the Go Gopher!

Note: Can't see the gopher?

  • Are you in the same directory as the gopher.go and gopher_test.go files (golang-samples-main/functions/codelabs/gopher)?
  • Is the server started? Be sure to build it with the go build -o start ./cmd command, then start it by running ./start. It should print Listening on localhost:8080.
  • Did you select the right port when opening the web preview? Be sure to use 8080, the port the server is listening on.

Task 5. Cleaning up

All resources you've used will be deleted when you end this lab. It's always a good idea to know what you would need to do on your own environment to save on cost and to be a good cloud citizen.

  1. Stop serving your URL with Ctrl + c.

  2. Once you're done testing your Cloud Functions, you can delete it using gcloud:

gcloud functions delete Gopher --region {{{project_0.default_region | REGION}}} gcloud functions delete HelloWorld --region {{{project_0.default_region | REGION}}}

You can also delete the function from the Cloud Console.


Now you know how to use Cloud Functions in Go! In this lab, you learned how to write an HTTP Cloud Function in Go, how to test it, and how to run it locally.

Finish your quest

This self-paced lab is part of the Getting Started with Go on Google Cloud quest. A quest is a series of related labs that form a learning path. Completing this quest earns you a badge to recognize your achievement. You can make your badge or badges public and link to them in your online resume or social media account. Enroll in this quest or any quest that contains this lab and get immediate completion credit. Refer to the Google Cloud Skills Boost catalog for all available quests.

Google Cloud training and certification

...helps you make the most of Google Cloud technologies. Our classes include technical skills and best practices to help you get up to speed quickly and continue your learning journey. We offer fundamental to advanced level training, with on-demand, live, and virtual options to suit your busy schedule. Certifications help you validate and prove your skill and expertise in Google Cloud technologies.

Manual Last Updated July 25, 2023

Lab Last Tested July 25, 2023

Copyright 2023 Google LLC All rights reserved. Google and the Google logo are trademarks of Google LLC. All other company and product names may be trademarks of the respective companies with which they are associated.

Provide Feedback on this Lab