--- title: "Go" slug: "cloudfunctions-example-go" tags: ["Cloud Functions", "Go"] updated: 2026-07-23T09:02:32Z published: 2026-07-23T09:02:32Z canonical: "guide-fin.ncloud-docs.com/cloudfunctions-example-go" --- > ## Documentation Index > Fetch the complete documentation index at: https://guide-fin.ncloud-docs.com/llms.txt > Use this file to discover all available pages before exploring further. # Go Go(Go Language) 형식의 액션을 생성하고 다양하게 활용하는 방법과 예제를 소개합니다. ## 액션 생성 Go 코드는 1개 이상의 Go 소스 파일을 가질 수 있습니다. Go 소스로 만든 Action의 진입점은 Main Package에 있는 함수입니다. Main 함수의 기본 이름은 Main이지만 사용자의 선택에 따라 다른 이름으로 변경할 수 있습니다. 하지만 이름의 시작점은 항상 대문자로 표기됩니다. 그리고 해당 Main 함수는 다음의 설명과 같은 형태로 생성해야 합니다. ``` func Main(event map[string]interface{}) map[string]interface{} ``` Go로 작성한 코드는 여러 개의 함수를 포함할 수 있지만 `main` 함수는 프로그램의 시작점으로서 반드시 선언되어야 합니다. 이 점을 고려하여 이름과 장소를 포함하여 "Hello World"를 출력하는 Go 형식의 간단한 예제 코드 `hello`는 다음과 같습니다. ``` 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 } ``` 위에서 작성한 코드를 사용하여 콘솔에서 'hello'라는 이름의 액션을 생성하는 과정은 다음과 같습니다. ![cloudfunctions-exmaple-go_v2_01_ko](https://cdn.document360.io/0406ed95-101f-4cde-8dd8-308d03444a94/Images/Documentation/cloudfunctions-example-go_v2_01_ko.png) ### 지원 가능 형태 실행 환경에서는 지원 가능한 형태는 다음과 같습니다. - AMD64 아키텍처용으로 컴파일된 Linux ELF 실행 파일의 실행 가능 바이너리 - AMD64 아키텍처용으로 컴파일된 Linux ELF 실행 파일을 포함하고 최상위에 `exec` 이름의 실행 파일을 포함하는 zip 파일 - Go에서 컴파일된 단일 소스 파일 - 최상위 레벨(폴더)에 실행 바이너리 파일을 포함하지 않은 zip 파일은 차후 컴파일되어 실행 참고 `GOOS=Linux`와 `GOARCH=amd64`로 모든 Go를 지원하는 플랫폼에서 올바른 형식의 바이너리를 크로스컴파일할 수 있습니다. 사전 컴파일 기능을 사용하여 실행 환경과 동일한 컴파일러를 사용하는 것이 더 안전합니다. ### Go Modules를 사용해서 액션 생성 go1.19 버전에서 외부 라이브러리를 사용하기 위해서는 `Go Modules`를 사용합니다. `Go Modules`를 사용하지 않는 경우, 소스 코드를 직접 포함해야 합니다. 다음은 `go mod`를 사용하여 액션에서 아래 패키지를 가져오는 방법에 대한 단계별 가이드입니다. 해당 방법은 인터넷 통신이 가능해야 하며, VPC 환경인 경우 NAT G/W 설정이 필요합니다. NAT G/W 관련 자세한 내용은 [NAT Gateway 사용 가이드](https://guide-fin.ncloud-docs.com/release-20260723/docs/networking-vpc-vpcdetailenatgw)를 참고해 주시기 바랍니다. ``` import "github.com/rs/zerolog" ``` 1. **새 모듈 초기화** 다음 명령을 실행하여 새 모듈을 초기화합니다. 해당 명령을 실행하면, `go.mod` 파일이 생성됩니다. ``` go mod init ``` 1. **`main.go` 작성** 아래 예제 코드를 참고하여 `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. **의존성 가져오기** 아래 명령을 실행하여 `go.mod` 파일을 업데이트하고, `go.sum` 파일을 생성합니다. ``` go get github.com/rs/zerolog@v1.19.0 ``` 1. **액션 패키징 및 업로드** 다음 명령을 실행하여 패키지를 압축하고 업로드하여 액션을 생성합니다. ``` zip -r action.zip go.mod go.sum main.go ``` ### 패지키와 `vendor`를 사용해서 액션 생성 코드를 작성하다 보면 하나의 액션 파일 외에 의존 파일들을 함께 패키징해야 하는 경우가 있습니다. 이러한 경우 관련된 파일들을 하나의 파일로 압축하여 패키징하고, 압축된 파일을 이용하여 액션을 생성할 수 있습니다. zip 파일을 이용하여 액션을 생성하는 경우 가능한 세 가지 형태는 다음과 같습니다. - `main` 패키지 안에 모든 기능을 구현한 경우 - `main` 패키지 이외에 일부 패키지를 분리하여 구성한 경우 - 기능 구현을 위해 외부 종속성을 가진 부분을 포함하는 형태로 구현한 경우(include third party dependencies) 만약 모든 기능이 기본 패키지에 있는 경우 모든 소스 파일을 zip 파일의 최상위 레벨에 배치하면 됩니다. #### 패키지 폴더 사용 일부 기능이 메인 함수 실행 부분과 다른 패키지에 속한다면 `hello/`와 같은 형태로 패키지 이름을 작성하여 폴더를 패키징해야 합니다. 패키징 예제는 다음과 같습니다. ``` golang-main-package/ - src/ - main.go - hello/ - hello.go - hello_test.go ``` 테스트를 실행하고 오류 없이 편집하려면 `src` 폴더를 사용해야 합니다. 기본 패키지의 내용들은 `src/` 하위에 위치하고, `hello` 패키지의 소스코드들은 `hello/` 폴더에 위치하게 합니다. 하지만 사용을 위해서는 필수적으로 하위 패키지를 `import "hello"`와 같이 불러와야 합니다. 이는 로컬 개발 환경에서 컴파일할 경우 사용자의 `GOPATH`에 `src`의 상위 디렉터리를 설정해야 한다는 의미입니다. 만약 사용자가 VSCode와 같은 편집기를 사용한다면 `go.inferGopath` 옵션을 활성화해야 합니다. 소스를 보낼 때 최상위 디렉터리가 아닌 `src` 폴더의 내용을 다음과 같이 압축해 주십시오. ``` cd src zip -r ../hello.zip * cd .. ``` 위 내용에 대한 예제 코드는 다음과 같습니다. `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"} } ``` #### `vendor` 폴더 사용 다른 3rd-party 라이브러리를 사용해야 하는 경우 런타임은 컴파일할 때 인터넷을 통해 해당 라이브러리를 다운로드하지 않고, `vendor` 폴더 구조를 사용해서 다운로드하고 배치해야 합니다. 여기서는 `dep` 도구를 사용하는 방법을 설명합니다. `vendor` 폴더는 `src` 폴더, 패키지 폴더, `vendor` 폴더를 포함해야 합니다. 최상위 폴더에서 작동하지 않습니다. 만약 `main` 패키지에 포함된 파일을 사용하기 위해서는 최상위 폴더가 아닌 `main`으로 명시된 하위 폴더에 배치해야 합니다. 예를 들어 파일 `src/hello/hello.go`에서 다음과 같은 패키지를 import해야 하는 상황을 가정해 보겠습니다. ``` import "github.com/sirupsen/logrus" ``` 이러한 경우 `vendor` 폴더를 생성하려면 다음과 같은 순서로 진행해 주십시오. 1. [dep](https://github.com/golang/dep) 도구를 설치해 주십시오. 2. `src/hello` 폴더로 이동해 주십시오. ``` cd ./src/hello ``` - `src` 폴더가 아니라 `src/hello`인 점에 주의해 주십시오. 3. `DEPPROJECTROOT=$(realpath $PWD/../..) dep init`를 실행해 주십시오. - 이 도구는 사용된 라이브러리를 탐색 및 감지하고 2개의 매니페스트 파일 `Gopkg.lock`, `Gopkg.toml`을 생성 - 이미 매니페스트 파일이 있는 경우 `dep ensure`를 실행하면 `vendor` 폴더가 생성되고 종속된 파일을 다운로드 구조를 정리하면 다음과 같습니다. ``` golang-hello-vendor - src/ - hello.go - hello/ - Gopkg.lock - Gopkg.toml - hello.go - vendor/ - github.com/... - golang.org/... ``` 위 내용에 대한 예제 코드는 다음과 같습니다. `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 } ``` 버전 관리 시스템에서 `vendor` 폴더를 다시 생성할 수 있으므로 별도로 저장할 필요가 없습니다. 매니페스트 파일만 저장하면 되지만 컴파일된 상태로 액션을 생성하려면 `vendor` 폴더를 포함해야 합니다. 만약 `main` 함수에서 3rd-party 라이브러리를 사용하려는 경우 최상위에 있는 main 패키지의 파일들을 `main` 폴더로 이동하여 `vendor` 폴더를 생성해야 합니다.