ディレクトリ構造
./
├─/cmd
│ └── main.go
├─/handlers
│ └── handlers.go
├── Dockerfile
├── go.mod
├── go.sum
├── cloudbuild.yaml
└── router.go
goのソース
main.go
package main
import (
"context"
"log"
router "github.com/yourname/gin"
"github.com/GoogleCloudPlatform/functions-framework-go/funcframework"
)
func main() {
ctx := context.Background()
gin := router.GinHandler
// 実行する関数の登録
if err := funcframework.RegisterHTTPFunctionContext(ctx, "/", gin); err != nil {
log.Fatalf("funcframework.RegisterHTTPFunctionContext: %v\n", err)
}
port := "8080"
if err := funcframework.Start(port); err != nil {
log.Fatalf("funcframework.Start: %v\n", err)
}
}
- ginから拝借した
handlers.go
package handlers
import (
"net/http"
"github.com/gin-gonic/gin"
)
type album struct {
ID string `json:"id"`
Title string `json:"title"`
Artist string `json:"artist"`
Price float64 `json:"price"`
}
var albums = []album{
{ID: "1", Title: "Blue Train", Artist: "John Coltrane", Price: 56.99},
{ID: "2", Title: "Jeru", Artist: "Gerry Mulligan", Price: 17.99},
{ID: "3", Title: "Sarah Vaughan", Artist: "Sarah Vaughan", Price: 39.99},
}
func GetAlbums(c *gin.Context) {
c.JSON(http.StatusOK, albums)
}
func PostAlbums(c *gin.Context) {
var newAlbum album
if err := c.BindJSON(&newAlbum); err != nil {
return
}
albums = append(albums, newAlbum)
c.JSON(http.StatusCreated, newAlbum)
}
router.go
import (
"net/http"
"github.com/yourname/gin/handlers"
"github.com/gin-gonic/gin"
)
func GinHandler(w http.ResponseWriter, r *http.Request) {
gin.SetMode(gin.ReleaseMode)
engine := gin.Default()
engine.GET("/hello", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "hello world",
})
})
engine.GET("/albums", handlers.GetAlbums)
engine.ServeHTTP(w, r)
}
Dockefile
FROM golang:1.22-alpine AS builder
WORKDIR /app
COPY . .
RUN go build -o main ./cmd/main.go
FROM alpine:latest
WORKDIR /app
COPY --from=builder /app/main .
CMD ["./main"]
Cloudbuild.yaml
steps:
# Cloud Run用のビルドとデプロイ
- name: 'gcr.io/cloud-builders/docker'
args: [ 'build', '-t', '${region}-docker.pkg.dev/${your-project-id}/${your-artifact-registry-reponame}/${image-name}:latest', '.' ]
- name: 'gcr.io/cloud-builders/docker'
args: ['push', '${region}-docker.pkg.dev/${your-project-id}/${your-artifact-registry-reponame}/${image-name}:latest']
- name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
entrypoint: gcloud
args: ['run', 'deploy', '${CloudRun-name}', '--image', '${region}-docker.pkg.dev/${your-project-id}/${your-artifact-registry-reponame}/${image-name}:latest', '--region', '${region}', '--platform', 'managed', '--allow-unauthenticated']
# Cloud Functions用のデプロイ
- name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
entrypoint: gcloud
args: ['functions', 'deploy', '${CloudFunctions-name}','--gen2', '--runtime', 'go122', '--trigger-http', '--entry-point', 'GinHandler', '--region', 'asia-northeast1','--source','.','--allow-unauthenticated']
CloudFunctionsの注意点
deployしたい関数(今回だとrouter.goのfun)とgo.modの階層が違うとエラーになります