この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
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
から名前を取り出してメッセージを生成します。エラー処理とか諸々適当なので、プロダクション環境で利用する場合は適宜修正して下さい。
function.go
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
コードは以下の通りです
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コマンドの開発等にも挑戦してみようと思います。