Go
    • PDF

    Go

    • PDF

    Article Summary

    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 actions

    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 the 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:

    compute-15-2-701.png

    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 file that contains ELF execution file compiled for AMD64 architecture, and execution file in the exec name 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.
    Note

    The correct form of binaries can be cross-compiled on all platforms that support Go 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 actions by using Go Modules

    For using external libraries in the go1.19 version, use Go Modules. When you're not using Go Modules, the source code must be directly included.
    Next is the stepwise guide on how to import the following package in actions using go mod: The relevant method requires the Internet communication and in a VPC environment, the NAT G/W settings are required. For more information about NAT G/W, see NAT Gateway Guide.

    import "github.com/rs/zerolog"
    
    1. Reset new modules

    Reset a new module by executing the following command: If you execute the command, a go.mod file will be created.

    go mod init <module>
    
    1. Create main.go

    See the following example code to create main.go:

    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
    }
    
    1. Import dependency

    Update go.mod file by executing the following command, and create go.sum file:

    go get github.com/rs/zerolog@v1.19.0
    
    1. Package and upload actions

    Compress the package by executing the following command and upload it to create actions:

    zip -r action.zip go.mod go.sum main.go
    

    Use package and vendor to create actions

    When writing codes, you may need to package dependency files along with one action file. In such cases, related files can be compressed in a file, packaged, and an action can be created using the compressed file.

    The following are the three types available for creating actions using ZIP files:

    • When all features are implemented in a main package
    • When some packages are separated and built other than the main package
    • When it is implemented in the form that includes parts that are dependent on third parties for feature implementation

    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 folder

    If some features belong to a different package than a part where the main function is executed, the folder needs to be packaged under a package name in the format such as 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, the src folder needs to be used. The default package's content is placed under src/, and the source codes of the hello package are placed in the hello/ folder. However, the sub-package must be imported like import "hello" to use it. This means that a parent directory of src must be set up in the user's GOPATH if compiled in a local development environment. If the user uses an editor such a VSCode, the go.inferGopath option needs to be enabled.
    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 the example code for the above:

    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 the vendor folder

    If a different third party library needs to be used, you don't download the runtime library via the Internet when compiling, but should use the vendor folder structure to download and place. 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 won't work on the top level folder. If you want to use files contained in the main package, it needs to be placed in the subfolder specified as main, rather than the top level folder. For example, let's suppose a circumstance where a package needs to be imported for the file src/hello/hello.go as follows:

    import "github.com/sirupsen/logrus"
    

    In such a case, proceed as follows to create the vendor folder.

    1. Install the dep tool.

    2. Go to the src/hello folder.

      cd ./src/hello
      
      • Note that it's not the src folder, but src/hello.
    3. Run DEPPROJECTROOT=$(realpath $PWD/../..) dep init.

      • This tool searches and detects libraries used, and creates 2 manifest files, Gopkg.lock and Gopkg.toml.
      • If there's a manifest file already, run dep ensure to create the vendor folder and download the dependent files.

    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 the example code for the above:

    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
    }
    

    The vendor folder may be created by the version control system, so it doesn't need to be saved separately. Only the manifest files need to be saved, but the vendor folder needs to be included to create a compiled action.
    If you want to use a third party library from the main function, you need to move the main package files on the top level to the main folder, and create the vendor folder.


    Was this article helpful?

    What's Next
    Changing your password will log you out immediately. Use the new password to log back in.
    First name must have atleast 2 characters. Numbers and special characters are not allowed.
    Last name must have atleast 1 characters. Numbers and special characters are not allowed.
    Enter a valid email
    Enter a valid password
    Your profile has been successfully updated.