📘

functions-framework-goを使ったCloud Functions 【Go言語】のHTTP関数作ってみる

2024/06/03に公開

はじめに

GoでCloud Functionsを使ってHTTP関数を作成して動かしてみました
goのworkspaceを使って、main関数から各関数を呼び出せるようにしています
これにより、関数ごとにディレクトリを分けて、拡張性を持たせることができます
Cloud Functionsにデプロイする際も、ディレクトリ毎にデプロイすることが可能です

環境

  • Go 1.21
  • Docker Compose

手順

  1. docker-compose.ymlを作成
  2. hello world関数を作成
  3. main関数を作成
  4. goのworkspaceを作成
  5. ローカルで動かす
  6. Cloud Functionsにデプロイ

0. 最終的なディレクトリ構成

.
├── functions
│   ├── helloworld
│   │   ├── go.mod
│   │   ├── go.sum
│   │   └── hello_http.go
|   ├── go.work
│   ├-- go.work.sum
│   └── main.go
└── docker-compose.yml

1. docker-compose.ymlを作成

後の拡張性を考慮して、docker-composeを使ってコンテナを作成します

version: "3.8"

services:
  functions:
    build: .
    image: golang:1.21.1-alpine
    ports:
      - "9081:8080"
    volumes:
      - ./functions:/var/www/functions
    container_name: functions-test
    tty: true
  gcloud:
    build: .
    image: google/cloud-sdk:latest
    volumes:
      - ./functions:/var/www/functions
    container_name: gcloud-test
    tty: true

2. hello world関数を作成

hello world関数を作成します
helloworldディレクトリを作成して、以下のファイルを作成します(hello_http.go)

// Package helloworld provides a set of Cloud Functions samples.
package helloworld

import (
        "encoding/json"
        "fmt"
        "html"
        "net/http"

        "github.com/GoogleCloudPlatform/functions-framework-go/functions"
	      _"github.com/GoogleCloudPlatform/functions-framework-go/funcframework"
)

func init() {
        functions.HTTP("HelloHTTP", HelloHTTP)
}

// HelloHTTP is an HTTP Cloud Function with a request parameter.
func HelloHTTP(w http.ResponseWriter, r *http.Request) {
        var d struct {
                Name string `json:"name"`
        }
        if err := json.NewDecoder(r.Body).Decode(&d); err != nil {
                fmt.Fprint(w, "Hello, World!")
                return
        }
        if d.Name == "" {
                fmt.Fprint(w, "Hello, World!")
                return
        }
        fmt.Fprintf(w, "Hello, %s!", html.EscapeString(d.Name))
}

Goのモジュールを初期化します ※functionsコンテナ内で実行

$ cd functions/helloworld
$ go mod init helloworld
$ go mod tidy

3. main関数を作成

main関数を作成します
以下のファイルを作成します(main.go)
importでhelloworldパッケージを読み込みます

package main

import (
	"log"
	"os"

	_ "helloworld"
	"github.com/GoogleCloudPlatform/functions-framework-go/funcframework"
)

func main() {
	// Use PORT environment variable, or default to 8080.
	port := "8080"
	if envPort := os.Getenv("PORT"); envPort != "" {
	  port = envPort
	}
	if err := funcframework.Start(port); err != nil {
	  log.Fatalf("funcframework.Start: %v\n", err)
	}
}

4. goのworkspaceを作成

main関数がhelloworldパッケージを読み込めるように、workspaceを使います
main.goがあるディレクトリで以下のコマンドを実行します ※functionsコンテナ内で実行

$ go work init
$ go work use helloworld

5. ローカルで動かす

go runでmain関数を実行します ※functionsコンテナ内で実行

$ go run main.go

http://localhost:9081にアクセスして、Hwllo, World!と表示されれば成功です!

6. Cloud Functionsにデプロイ

デプロイするために、helloworldで使用しているgoのライブラリを取得します ※functionsコンテナ内で実行

$ cd helloworld
$ go mod vendor

gcloudコンテナに入り、デプロイします ※gcloudコンテナ内で実行

$ gcloud auth login
$ gcloud config set project <PROJECT_ID>
$ gcloud functions deploy HelloHTTP --gen2 --runtime=go121 --source=helloworld/ --trigger-http --entry-point HelloHTTP --allow-unauthenticated

デプロイが成功すると、URLが表示されます
URLにアクセスして、Hello, World!が表示されれば成功です!

参考

https://cloud.google.com/functions/docs/create-deploy-http-go?hl=ja
https://qiita.com/Rqixy/items/6bdead71dc02eb233376

株式会社フライヤー Tech Blog

Discussion