Available in Classic and VPC
This document describes how to create and use actions of Go (as a language) format in a variety of ways, and application examples.
Create action
A Go code can have one or more Go source files. The entry point of an action made with Go sources is a function in the main package. The main function's default name is Main, but can be modified to a different name depending on the user's choice. However, the name always starts with an uppercase English letter. The main function needs to be created in the format detailed in the following description:
func Main(event map[string]interface{}) map[string]interface{}
A code written in Go may contain multiple functions, but the main function must be declared as the starting point of a program. With this taken into account, the following is a simple example code hello in Go, printing "Hello World" along with a name and location:
package main
import "log"
func Main(obj map[string]interface{}) map[string]interface{} {
name, ok := obj["name"].(string)
if !ok {
name = "world"
}
msg := make(map[string]interface{})
msg["message"] = "Hello, " + name + "!"
log.Printf("name=%s\n", name)
return msg
}
The following is the process of an action called "hello" in the console, using the code written above.

Supported formats
The following are formats that can be supported in the execution environment:
- Executable binary of a Linux ELF execution file compiled for AMD64 architecture
- ZIP files containing Linux ELF executable files compiled for AMD64 architecture with an executable named exec at the top level
- Single source file compiled in Go
- ZIP files that don't contain execution binary files on the top level (folder) are compiled and executed later.
You can cross-compile binaries in the correct format on any Go-supporting platform with GOOS=Linux and GOARCH=amd64. It's safer to use the advance compile feature and use the same compiler as in the execution environment.
Create action using Go Modules
For using external libraries in the go1.19 version, use Go Modules. Without Go Modules, you must include source code directly.
Next is the stepwise guide on how to import the following package in actions using go mod: The relevant method requires Internet communication and NAT G/W settings are required in a VPC environment. For more information about NAT G/W, see NAT Gateway Guide.
import "github.com/rs/zerolog"
- Initialize new modules
Initialize new module by executing the following command. Running the command will create a go.mod file.
go mod init <module>
- Write main.go
To write main.go, see the following example code:
package main
import (
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
)
func init() {
zerolog.TimeFieldFormat = ""
}
func Main(obj map[string]interface{}) map[string]interface{} {
name, ok := obj["name"].(string)
if !ok {
name = "world"
}
log.Debug().Str("name", name).Msg("Hello")
msg := make(map[string]interface{})
msg["module-main"] = "Hello, " + name + "!"
return msg
}
- Import dependency
Run the command below to update go.mod file and create go.sum file.
go get github.com/rs/zerolog@v1.19.0
- Package and upload action
Run the following command to compress the package and create an action by uploading.
zip -r action.zip go.mod go.sum main.go
Create action using packages and vendor
When writing codes, you may need to package dependency files along with one action file. In this case, you can compress related files into one file for packaging and create an action using the compressed file.
The following are the three types available for creating actions using ZIP files:
- All functionality implemented in main package
- Some packages separated from main package
- Implementation including parts with external dependencies (include third party dependencies)
If all features are in a default package, you can place all the source files in the top level of the ZIP file.
Use package folders
If some functionality belongs to packages other than the main function execution part, you must package folders with package names like hello/. The following is a packaging example:
golang-main-package/
- src/
- main.go
- hello/
- hello.go
- hello_test.go
To run tests and edit without errors, use the src folder. Default package contents go under src/, and hello package source code goes in the hello/ folder. However, you must import subpackages like import "hello". This means setting the src parent directory in your GOPATH for local compilation. If using an editor like VSCode, enable the go.inferGopath option.
When sending the source, compress the src folder's content, rather than the top directory as follows:
cd src
zip -r ../hello.zip *
cd ..
The following is an example code for the above information:
- src/main.go
package main
import (
"fmt"
"hello"
)
// Main forwading to Hello
func Main(args map[string]interface{}) map[string]interface{} {
fmt.Println("Main")
return hello.Hello(args)
}
- src/hello/hello.go
package hello
import (
"fmt"
)
// Hello receive an event in format
// { "name": "Mike"}
// and returns a greeting in format
// { "greetings": "Hello, Mike"}
func Hello(args map[string]interface{}) map[string]interface{} {
res := make(map[string]interface{})
greetings := "world"
name, ok := args["name"].(string)
if ok {
greetings = name
}
res["golang-main-package"] = "Hello, " + greetings
fmt.Printf("Hello, %s\n", greetings)
return res
}
- src/hello/hello_test.go
package hello
import (
"encoding/json"
"fmt"
)
func ExampleHello() {
var input = make(map[string]interface{})
input["name"] = "Mike"
output := Hello(input)
json, _ := json.Marshal(output)
fmt.Printf("%s", json)
// Output:
// Hello, Mike
// {"golang-main-package":"Hello, Mike"}
}
func ExampleHello_noName() {
var input = make(map[string]interface{})
output := Hello(input)
json, _ := json.Marshal(output)
fmt.Printf("%s", json)
// Output:
// Hello, world
// {"golang-main-package":"Hello, world"}
}
Use vendor folder
When using third-party libraries, the runtime should use vendor folder structure to download and place libraries instead of downloading them through the Internet during compilation. This page provides instructions on how to use the dep tool.
The vendor folder must include the src folder, package folder, and vendor folder. It doesn't work in the top-level folder. To use files included in the main package, place them in a subfolder specified as main, not the top-level folder. For example, let's consider a situation where you need to import packages in file src/hello/hello.go.
import "github.com/sirupsen/logrus"
To create a vendor folder, take the following steps:
-
Install the dep tool.
-
Go to src/hello folder.
cd ./src/hello- Note that it's src/hello, not src.
-
Run
DEPPROJECTROOT=$(realpath $PWD/../..) dep init.- This tool detects used libraries and creates two manifest files, Gopkg.lock and Gopkg.toml.
- If manifest files already exist, running dep ensure creates the vendor folder and downloads dependencies.
The summarized structure is as follows:
golang-hello-vendor
- src/
- hello.go
- hello/
- Gopkg.lock
- Gopkg.toml
- hello.go
- vendor/
- github.com/...
- golang.org/...
The following is an example code for the above information:
- hello.go
package main
import (
"fmt"
"hello"
)
// Main forwading to Hello
func Hello(args map[string]interface{}) map[string]interface{} {
fmt.Println("Entering Hello")
return hello.Hello(args)
}
- hello/hello.go
package hello
import (
"os"
"github.com/sirupsen/logrus"
)
var log = logrus.New()
// Hello receive an event in format
// { "name": "Mike"}
// and returns a greeting in format
// { "greetings": "Hello, Mike"}
func Hello(args map[string]interface{}) map[string]interface{} {
log.Out = os.Stdout
res := make(map[string]interface{})
greetings := "world"
name, ok := args["name"].(string)
if ok {
greetings = name
}
res["golang-hello-vendor"] = "Hello, " + greetings
log.WithFields(logrus.Fields{"greetings": greetings}).Info("Hello")
return res
}
You don't need to save the vendor folder separately because it can be recreated from the version control system. While saving manifest files is sufficient, you must include the vendor folder to create actions in compiled state.
If you want to use third-party libraries in the main function, move main package files at the top level to the main folder to create the vendor folder.