Go言語とGoogle Cloud Functionsで、URLを渡すとOGPメタデータをjsonで返してくれるAPIを作る
19年3月にGoogle Cloud FunctionsがGo言語を正式サポートしていたとのことで、URLを渡すとOGP+αが取得できるCloud Functionsを作ってみました。
環境は以下の通り。
$ go version
go version go1.12.7 darwin/amd64
$ gcloud version
Google Cloud SDK 256.0.0
beta 2019.05.17
bq 2.0.46
core 2019.07.26
gsutil 4.41
$ hugo version
Hugo Static Site Generator v0.55.6/extended darwin/amd64 BuildDate: unknown
以下ステップバイステップで作り方をみていきます。
GCPでプロジェクトを作る
cloud-functions-test
という名前でプロジェクトを作ります。
gcloud CLI(Cloud SDK)のインストール&セットアップ
Google Cloud SDK documentation | Cloud SDK | Google Cloudの内容に従いCloud SDKをインストールします。 インストール後はCloud SDKのコンポーネントのアップデートと、先に作成したプロジェクトの選択と、そのプロジェクトでCloud Functionsを有効化しておきます。
$ gcloud components update
All components are up to date.
$ gcloud projects list
PROJECT_ID NAME PROJECT_NUMBER
cloud-functions-test-248711 cloud-functions-test 673440494381
$ gcloud config set project cloud-functions-test-248711
Updated property [core/project].
$ gcloud services enable cloudfunctions.googleapis.com
Operation "operations/acf.********-****-****-****-************" finished successfully.
コードを書く前に
まずざっと以下の資料に目を通して、どうすべきかを把握しておきます。ちなみに8/3時点では日本語版は内容が古いようので、英語版を見る必要ありです。
- HTTP Tutorial | Cloud Functions Documentation | Google Cloud
- Specifying dependencies in Go | Cloud Functions Documentation | Google Cloud
- Deploying from Your Local Machine | Cloud Functions Documentation | Google Cloud
- gcloud functions deploy | Cloud SDK | Google Cloud
- Events and Triggers | Cloud Functions Documentation | Google Cloud
まとめると、
- サポートしているGoのバージョンはGo 1.11
HTTPリクエストで発火させる場合は、
func Handler(w http.ResponseWriter, r *http.Request) { }
のような
net/http
のhttp.HandleFunc
に食わせるのと同様の関数を実装する依存関係の解消はGo modulesか、vendorディレクトリに置くかのいずれか
- ただし、go.modが存在する場合はvendorディレクトリは無視されるので、vendorで管理しているはずなのにうまく動かない場合はgo.modが存在しないか確認する
コードを書く
$GOPATH
内にプロジェクトがある- Go modulesで依存関係を管理する
👆を前提にSpecifying dependencies in Go | Cloud Functions Documentation | Google Cloudを見ながらコードを書きます。
$ mkdir $GOPATH/src/github.com/nishim/gogp
$ cd $GOPATH/src/github.com/nishim/gogp
$ export GO111MODULE=on
$ go mod init
$ vi gogp.go
コンソールでも確認できます。 書いたコードはGitHubにあります。コードが書き終わったら依存関係のアップデートをしておきます。
$ go mod tidy
デプロイする
gcloud CLIでデプロイします。出力にもある通り、少しだけ時間がかかります。
$ gcloud functions deploy Gogp --runtime go111 --trigger-http --memory=128MB
Deploying function (may take a while - up to 2 minutes)...done.
availableMemoryMb: 128
entryPoint: Gogp
httpsTrigger:
url: https://us-central1-cloud-functions-test-248711.cloudfunctions.net/Gogp
labels:
deployment-tool: cli-gcloud
name: projects/cloud-functions-test-248711/locations/us-central1/functions/Gogp
runtime: go111
serviceAccountEmail: cloud-functions-test-248711@appspot.gserviceaccount.com
sourceUploadUrl: https://storage.googleapis.com/gcf-upload-us-central1-7da3dd30-c7fd-4789-a282-7caaae91b03d/f9be229c-5e24-4702-9ff3-6fc00143bb22.zip?GoogleAccessId=service-673440494381@gcf-admin-robot.iam.gserviceaccount.com&Expires=1564836842&Signature=dd%2FoJW4P%2F0xAJbg9mnbV861VP6eT6ylifuYyUEkDRA0Tes8xUBmH8sx1rsogF3k%2BImvLs37CX1JPcnOp4vVxrQSyEMZ8%2BiFhA2SluC7PjxNzQDLOX9q4Du6uudrUNExgUUx0mmIawQieQTtSnrPY0aFSo3heh5jiKg1uJrawxOPVac0bxBftF0nYqEX82L24xwVNh6p4D%2FMjQPcdZY1Nradj5dzt4yzIbv82urbOdS47z7ZyVFxk2Z5IlYzcy8n%2BoMg%2BUl1U1Lte%2FL%2B%2BsMgzFtfPSx7nOCoOLt3u%2FxgauVLw2a40qLtb7t6DzZCRYUC87MqhSQ7%2FwEeaR7ON5bSDWg%3D%3D
status: ACTIVE
timeout: 60s
updateTime: '2019-08-03T12:24:40Z'
versionId: '1'
これでデプロイできました。httpsTrigger
にあるのがエンドポイントになります。試しにcurlして見ると?
$ curl -s "https://us-central1-cloud-functions-test-248711.cloudfunctions.net/Gogp?url=https%3a%2f%2fblog%2eliclab%2ecom%2f2019%2d06%2d17%2fgo%2dx%2dnet%2dhtml%2dutf8%2dbom%2f" | python -m json.tool
{
"description": "Go\u306egolang.org/x/net/html\u30d1\u30c3\u30b1\u30fc\u30b8\u3067BOM\u4ed8\u304dUTF-8\u306b\u3084\u3089\u308c\u305f\u8a71",
"favicon": "",
"image": "",
"site_name": "",
"site_url": "https://blog.liclab.com/",
"title": "Go\u306egolang.org/x/net/html\u30d1\u30c3\u30b1\u30fc\u30b8\u3067BOM\u4ed8\u304dUTF-8\u306b\u3084\u3089\u308c\u305f\u8a71",
"type": "article",
"url": "https://blog.liclab.com/2019-06-17/go-x-net-html-utf8-bom/"
}
うまくいきました。コンソールでも確認できます。
おわりに
基本的にはGoでWebアプリを作る時と同じことをするだけなので、お手軽でいいですね。料金もAlways Free枠が大きくプライベートユースであれば無料枠内で問題なく利用できそうです。
次はこのAPIを利用して、Hugoでブログカードを利用できるようにしていきます。