📘
functions-framework-goを使ったCloud Functions 【Go言語】のHTTP関数作ってみる
はじめに
GoでCloud Functionsを使ってHTTP関数を作成して動かしてみました
goのworkspaceを使って、main関数から各関数を呼び出せるようにしています
これにより、関数ごとにディレクトリを分けて、拡張性を持たせることができます
Cloud Functionsにデプロイする際も、ディレクトリ毎にデプロイすることが可能です
環境
- Go 1.21
- Docker Compose
手順
- docker-compose.ymlを作成
- hello world関数を作成
- main関数を作成
- goのworkspaceを作成
- ローカルで動かす
- 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!が表示されれば成功です!
参考
Discussion