【初心者向け】Cloud Functionsを使ってojichatをHTTP API化してみた

ヤッホー(^_^)?☀ (笑)?Cloud FunctionsでojichatをHTTP API化してみたヨ????
2021.12.10

この記事は公開されてから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コマンドの開発等にも挑戦してみようと思います。