【GCP】CloudEndpoints+CloudFunctionsでWebAPIを構築する

【GCP】CloudEndpoints+CloudFunctionsでWebAPIを構築する

GCPでWebAPIを作成するときには、CloudEndpointsと呼ばれるサービスを利用してAPIを管理するかと思います。

この記事では、WebAPIをCloudFunctionsで立ち上げて、CloudFunctionsの手前にCloudEndpointsを配置する方法を紹介します。

下記が想定する構成図です。

ポイント
  • APIはCloud Functionsに立ち上げる
  • Cloud EndpointsはAPIゲートウェイとしてESPv2を利用する
  • ESPv2はCloudRun上にデプロイされる
  • ESPv2は”Endpoints”サービスにデプロイされているEndpointsサービスを参照する

CloudEndpointsを理解する上で重要なのは、EndpointsのデプロイAPIゲートウェイのデプロイは異なるという点です!

Endpointsサービスへのデプロイ+APIゲートウェイのデプロイすることで、”CloudEndpoints”を利用していることになります!

Cloud Endpointsとは

Cloud Endpointsは、Google Cloudで提供されているサービスの一つで、APIの管理のために利用されます(Cloud Endpoints: https://cloud.google.com/endpoints?hl=ja)。

主に利用される機能として、下記があげられます。

  • APIの呼び出しに認証機能を追加
  • 利用状況のモニタリング
  • API呼び出し回数の制限(Rate Limiting)
  • APIのドキュメント化

上記はどれも重要な機能ですよね。

許可されたユーザのみに利用させるための認証機能や、1分間あたりのリクエスト数に制限をつけるRateLimitingなど、APIを公開するうえで非常に重要な機能を提供してくれます。

Cloud Endpointsは、APIを外部に公開する場合はほぼ必須のサービスです!

CloudEndpointsの理解に向けて

CloudEndpointsはちょっとわかりにくいですが、冒頭で述べた通り下記を抑えておくとかなり理解が簡単になります。

  • APIゲートウェイの機能はExtensible Service Proxy V2(ESPv2)と呼ばれるプロキシ上で動作する
  • ESPv2はコンテナとしてGCPから提供されており、CloudRun上で動作させる
  • ESPv2の設定は、”Endpoints”と呼ばれるサービスにデプロイする必要がある
  • Endpointsサービスは、OpenAPIドキュメントで構成される

CloudEndpointsの構築

それでは、CloudEndpointsを構築していきます。

基本的に、公式ドキュメント通りデプロイを進めていきます。

ESPv2 を使用した Cloud Run 用の Endpoints のスタートガイド: https://cloud.google.com/endpoints/docs/openapi/get-started-cloud-run?hl=ja#deploy_configuration

CloudRunにホスト名を予約

上記で述べている通り、APIゲートウェイはCloudRun上に作成します。

なのでまず、APIゲートウェイをデプロイするCloudRunのホスト名を事前に予約します。

設定するべき環境変数は下記になります。実際は環境変数にする必要はないですが、今後のコマンドでも利用するので環境変数化しておくのが便利です。

環境変数値例説明
CLOUD_RUN_SERVICE_NAMEapi-gatewayCloudRunに構築するESPv2のサービス名
ESP_PROJECT_IDsample-pjESPv2をデプロイするGCPプロジェクト名

下記を実行してCloudRunにサービスをデプロイして、ホスト名を予約しましょう。

# リージョンの設定
$ gcloud config set run/region us-central1
# Helloプログラムをデプロイ
$ export CLOUD_RUN_SERVICE_NAME=api-gateway
$ export ESP_PROJECT_ID=sample-pj
$ gcloud run deploy $CLOUD_RUN_SERVICE_NAME \ --image="gcr.io/cloudrun/hello" \ --allow-unauthenticated \ --platform managed \ --project=$ESP_PROJECT_ID
...
Service [api-gateway] revision [api-gateway-00001] has been deployed and is serving traffic at https://api-gateway-12345-uc.a.run.app

gcloud run deployコマンドを実行すると上記のような出力を得られるので、予約したホスト名を環境変数に格納しておきましょう。

環境変数値例説明
CLOUD_RUN_HOSTNAMEapi-gateway-12345-uc.a.run.appESPv2をデプロイするホスト名。https://api-gateway-12345-uc.a.run.appの、https://を除いた部分

Endpointsの設定(YAMLファイルの作成)

OpenAPI v2の仕様に従って、Endpointsの設定を行います。

この設定は、”Endpoints”サービスにデプロイします。

まずは、設定するべき環境変数(実際はOpenAPIドキュメントに書き込む変数)です。

環境変数値例説明
REGIONus-central1WebAPIがデプロイされているリージョン
PROJECT_IDsample-pjWebAPIがデプロイされているプロジェクトID。今回はESPv2と同じプロジェクト内にデプロイされていることを想定
FUNCTIONS_NAMEhelloGETCloudFunctionsの関数名

上記の設定値をもとに、下記の設定ファイル(opeanapi.yml)を作成しましょう。

swagger: '2.0'
info: title: Cloud Endpoints + GCF description: Sample API on Cloud Endpoints with a Google Cloud Functions backend version: 1.0.0
host: CLOUD_RUN_HOSTNAME
schemes: - https
produces: - application/json
paths: /hello: get: summary: Greet a user operationId: hello x-google-backend: address: https://REGION-FUNCTIONS_PROJECT_ID.cloudfunctions.net/FUNCTIONS_NAME protocol: h2 responses: '200': description: A successful response schema: type: string

Endpoints構成のデプロイ

先ほど作成したYAMLファイルをEndpointsサービスにデプロイします。

$ gcloud endpoints services deploy openapi-functions.yaml \ --project ESP_PROJECT_ID
...
Service Configuration [2021-08-22r0] uploaded for service [gateway-12345-uc.a.run.app]

ESPv2でこの設定を参照することになるので、ESPv2がデプロイされているプロジェクトと同じプロジェクトにEndpointsの設定をデプロイする必要があります。

ここで作成した設定ファイルを参照するために必要な情報を出力結果から取得しましょう

環境変数値例説明
CONFIG_ID2021-08-22r0EndpointsのバージョンIDです。”日付-リビジョン番号”で表現されています。

サービスの有効化

Endpoints機能を利用できるようにするため、必要なサービスを有効化していきます。

CLOUD_RUN_HOSTNAMEを有効化するのがポイントです。

$ gcloud services enable servicemanagement.googleapis.com
$ gcloud services enable servicecontrol.googleapis.com
$ gcloud services enable endpoints.googleapis.com
$ gcloud services enable $CLOUD_RUN_HOSTNAME

ESPv2イメージのビルドとイメージのデプロイ

ESPv2のイメージを作成し、作成したイメージをCloudRunにデプロイしていきます。

まずイメージを作成していきましょう。

下記ページからイメージ作成用のシェルスクリプトを取得して、イメージを作成しましょう。

https://github.com/GoogleCloudPlatform/esp-v2/tree/master/docker/serverless/gcloud_build_image

$ chmod +x gcloud_build_image
$ ./gcloud_build_image -s CLOUD_RUN_HOSTNAME \ -c CONFIG_ID -p ESP_PROJECT_ID
...
gcr.io/sample-pj/endpoints-runtime-serverless:2.30.1-api-gateway-12345-uc.a.run.app-2021-08-22r0

上記コマンドからわかるように、ここでEndpointsのCONFIG_IDを指定することで、Endpointsの設定をESPv2(APIゲートウェイ)に伝えることができます。

また、出力結果に含まれるイメージのパスから、ESP_VERSIONを確認しましょう。

環境変数値例説明
ESP_VERSION 2.30.1ESPのバージョン。gcr.io/ESP_PROJECT_ID/endpoints-runtime-serverless:ESP_VERSION-CLOUD_RUN_HOSTNAME-CONFIG_IDを参考に上記出力から取得

次に、作成したイメージファイルを利用してCloudRunにESPv2をデプロイしていきます。

$ export ESP_VERSION=2.30.1
$ gcloud run deploy $CLOUD_RUN_SERVICE_NAME \ --image="gcr.io/${ESP_PROJECT_ID}/endpoints-runtime-serverless:${ESP_VERSION}-${CLOUD_RUN_HOSTNAME}-${CONFIG_ID}" \ --allow-unauthenticated \ --platform managed \ --project=${ESP_PROJECT_ID}

これで、CloudEndpointsの構築が完了です。

動作確認

実際にGETリクエストを送って、CloudEndpointsのテストをします。

$ export ENDPOINTS_HOST=gateway-12345-uc.a.run.app
$ curl --request GET \ --header "content-type:application/json" \ "https://${ENDPOINTS_HOST}/hello"

200のHTTPステータスが得られていれば、CloudEndpoints+CloudFunctionsのデプロイが成功です。

まとめ

CloudEndpoints+CloudFunctionsのデプロイ方法を紹介しました。

ほぼ公式ドキュメント通りですが、初見では中々難しいと思います。

自分が躓いたポイントを書きつつまとめたので、参考になれば幸いです。

次回は、APIのパスに独自のドメインを設定する方法や、サービスアカウントを利用したRatingLimitの設定方法などを紹介します。