【初心者向け】Cloud Functionsを使ってojichatをHTTP API化してみた
MAD事業部@大阪の岩田です。
本エントリはクラスメソッド Google Cloud Advent Calendar 2021の10日目の記事です。
私の所属するMAD事業部では近年ojichatを利用したサービスを構築する機会が増えているようです。
私もojichatを使ったAPIぐらいはサクッと構築できるようにならないとMAD事業部の流行から取り残されそうな危機感を感じたので、Cloud Functionsを使ったojichatのHTTP API構築に挑戦してみました。
環境
今回利用した環境です
- Go : 1.16.7
- Functions Framework for Go : v1.5.2
- ojichat: v0.2.2
やってみる
ということでさっそくやっていきます。ローカル環境でAPIを開発し、動作確認が取れたらGoogle Cloud上にデプロイして動かしていきます。
ローカル環境でojichatのAPIを動かしてみる
まずはローカル環境でojichatのAPIを動かしてみましょう。ローカル環境でCloud Functionsを開発するにはFunction Frameworkが有用です。まずはローカル環境でFunction Framework経由でojichatのHTTP APIを動作させるまでやってみます。
まずはプロジェクト用のディレクトリを作成
$ mkdir ojichat-api $ cd ojichat-api
モジュールを初期化します
$ go mod init iwata.example.com/ojichat-api
※iwata.example.com/ojichat-apiの部分は適宜変更して下さい
続いてFunctions Framework for Goとojichatを導入します
$ go get github.com/GoogleCloudPlatform/functions-framework-go/funcframework $ go get github.com/greymd/ojichat
Cloud Functionsにデプロイする関数の本体を作成します
$ touch function.go
ソースコードはこちらです。GETメソッドでアクセスされた場合に、クエリストリングname
から名前を取り出してメッセージを生成します。エラー処理とか諸々適当なので、プロダクション環境で利用する場合は適宜修正して下さい。
package ojichatapi import ( "net/http" "fmt" "github.com/greymd/ojichat/generator" ) func Ojichat(w http.ResponseWriter, r *http.Request) { switch r.Method { case http.MethodGet: name := r.URL.Query().Get("name") config := generator.Config{ TargetName: name, EmojiNum: 4, PunctuationLevel: 0, } ojiResult, _ := generator.Start(config) fmt.Fprint(w, ojiResult) default: http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed) } }
続いて上記の関数をFunctions Framework for Go経由で呼び出すためのローカル開発サーバーのコードを用意します
$ mkdir cmd $ touch cmd/main.go
コードは以下の通りです
package main import ( "log" "os" "context" "github.com/GoogleCloudPlatform/functions-framework-go/funcframework" "iwata.example.com/ojichat-api" ) func main() { ctx := context.Background() if err := funcframework.RegisterHTTPFunctionContext(ctx, "/", ojichatapi.Ojichat); err != nil { log.Fatalf("funcframework.RegisterHTTPFunctionContext: %v\n", err) } // 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) } }
これでローカル環境でojichatのAPIを起動する準備ができました。以下のコマンドを実行し、ローカルの開発サーバーを起動してみましょう。
$ go run cmd/main.go Serving function:
これでローカル環境の8080ポートでサーバーが起動します。起動が確認できたらCURLコマンドで動作確認してみましょう
$ curl localhost:8080?name=智哉 智哉チャン、会社をサボるなんて、悪い子だなぁ?なんちゃって?❗??今日はもう寝ちゃったのかな??(^^;;(# ̄З ̄)寒いけど、頑張ってね
Cloud Functions環境にデプロイして動かしてみる
ローカル環境で動作確認が取れたらCloud Functions環境にデプロイしてみましょう。
$ gcloud functions deploy Ojichat --runtime go116 --trigger-http --allow-unauthenticated --entry-point=Ojichat
色んな人にAPIを叩いてもらいたいので、--allow-unauthenticated
を指定して未認証状態でアクセスできるようにしています。
しばらく待つとデプロイが完了し、エンドポイントのURLが出力されます
Deploying function (may take a while - up to 2 minutes)...⠛ For Cloud Build Logs, visit: https://console.cloud.google.com/cloud-build/builds;region=us-central1/d96c42f1-c995-4843-80a0-f0f09d2c9d6f?project=<Google CloudのプロジェクトID> Deploying function (may take a while - up to 2 minutes)...done. availableMemoryMb: 256 buildId: d96c42f1-c995-4843-80a0-f0f09d2c9d6f buildName: projects/<Google CloudのプロジェクトID>/locations/us-central1/builds/d96c42f1-c995-4843-80a0-f0f09d2c9d6f entryPoint: Ojichat httpsTrigger: securityLevel: SECURE_ALWAYS url: https://us-central1-<Google Cloudのプロジェクト名>.cloudfunctions.net/Ojichat ingressSettings: ALLOW_ALL labels: deployment-tool: cli-gcloud name: projects/<Google Cloudのプロジェクト名>/locations/us-central1/functions/Ojichat runtime: go116 serviceAccountEmail: <Google Cloudのプロジェクト名>@appspot.gserviceaccount.com sourceUploadUrl: https://storage.googleapis.com/gcf-upload-us-central1-<UUIDらしき文字列>/<UUIDらしき文字列>.zip status: ACTIVE timeout: 60s updateTime: '2021-12-09T07:51:22.422Z' versionId: '1'
マネコンからもデプロイに成功していることが分かります
先程のローカル環境と同様にCURLコマンドで動作を確認してみます。
$ curl https://us-central1-<Google Cloudのプロジェクト名>.cloudfunctions.net/Ojichat?name=智哉 あれ?^^;智哉チャン、朝と夜間違えたのかな⁉オレはまだ起きてますよ〜?♥ ❗ちょっと電話できるかナ?⁉️✋❓?⁉そろそろご飯行こうよ?(笑)??♥ ご要望とかはあるのカナ??⁉️
成功です。これでいつでもオジサンからのメッセージを受け取れます。
まとめ
HTTPトリガーのCloud Functionsを使うとちょっとしたWeb APIが簡単に構築できることが分かりました。各種SaaSとの連携用にサクッとコールバックURLを用意したい場合など非常に便利に使えそうです。今度はSlackコマンドの開発等にも挑戦してみようと思います。