Visual Studio Code を使用した Cloud Functions での Node.js 向けローカル開発

1. 概要

Google Cloud Functions は、イベント ドリブン型のサーバーレス コンピューティング プラットフォームです。Cloud Functions を使用すると、リソースのプロビジョニングや、変化する要件に対応するためのスケーリングを気にすることなく、コードを記述できます。

JavaScript で記述された Cloud Functions は、Google Cloud Platform の Node.js 環境で実行されます。Cloud Functions の関数は標準的な Node.js ランタイムで実行できるため、移植性とローカルテストが容易になります。

チュートリアル

この Codelab では、指定された温度が許容範囲内か、高すぎるかを報告する Node.js 用の Cloud Functions を作成します。ローカルマシンの Visual Studio Code を使用して、Cloud Functions を作成、テスト、デバッグします。最後に、関数を Google Cloud Platform にデプロイします。

学習内容

  • Functions Framework for Node.js。
  • HTTP Cloud Functions の関数を作成してローカルでテストする。
  • ローカルマシンから HTTP 関数をデバッグします。
  • ローカルマシンから HTTP 関数をデプロイします。

2. 設定と要件

前提条件

費用

この Codelab では、デプロイされた Cloud Functions の呼び出しは 1 回のみですが、Cloud Functions API の料金情報を参照して、課金の仕組みを理解する必要があります。

多くの Google API は無料でご利用いただけますが、Google Cloud Platform(プロダクトと API)の使用は有料です。Cloud Functions を使用するには、有効な請求先アカウントが必要です。一部の Google Cloud Platform(GCP)プロダクトには、超過した場合のみに料金が発生する Always Free 枠が用意されています。このコードラボでは、Cloud Functions の呼び出しごとに無料枠が消費されます。使用量の合計が上限(月ごと)を超えない限り、料金は発生しません。

3. Node.js 用 Functions Framework をインストールする

Functions Framework for Node.js は、ポータブルな Node.js 関数を記述するためのオープンソースの FaaS(Function as a Service)フレームワークです。これは Google Cloud Functions チームによって提供されています。

Functions Framework を使用すると、次のようなさまざまな環境で実行される軽量関数を作成できます。

  • Google Cloud Functions
  • ローカル開発マシン
  • Cloud Run および Cloud Run on GKE
  • Knative ベースの環境

新しい node.js アプリを作成します。

npm init

デフォルトを受け入れる際は、アプリのエントリ ポイントとして index.js を使用するようにしてください。

次に、Functions Framework for Node.js をインストールします。

npm install @google-cloud/functions-framework

package.json を開きます。次の例に示すように、関数フレームワークが依存関係としてリストされていることを確認します。

"dependencies": {
   "@google-cloud/functions-framework": "^1.7.1"
 }

これで、Functions Framework が正常にインストールされました。これで、Cloud Functions の関数を作成する準備が整いました。

4. HTTP Cloud Functions をローカルで作成してテストする

ローカル Cloud Functions の関数を作成する

このセクションでは、HTTP リクエストに応答する HTTP 関数を作成してテストします。

package.json ファイルと同じディレクトリに index.js という新しいファイルを作成します。

次のものを追加します。

exports.validateTemperature = async (req, res) => {
 try {
   if (req.body.temp < 100) {
     res.status(200).send("Temperature OK");
   } else {
     res.status(200).send("Too hot");
   }
 } catch (error) {
   //return an error
   console.log("got error: ", error);
   res.status(500).send(error);
 }
};

これで、関数をテストする準備が整いました。

Visual Studio Code で関数をテストする

この Codelab では、Visual Studio Code 内の 統合ターミナルを使用します。

Visual Studio Code でターミナル ウィンドウを開きます。

次のコマンドを実行します。

node node_modules/@google-cloud/functions-framework --target=validateTemperature

このコマンドは、サーバーが HTTP リクエストを受信したときに validateTemperature 関数を呼び出す準備ができているローカル サーバーを起動します。

ターミナル ウィンドウに次の出力が表示されます。

Serving function...
Function: validateTemperature
URL: http://localhost:8080/

VS Code 内に 2 つ目のターミナル ウィンドウを作成するには、ターミナル ウィンドウ ペインの New Terminal プラスアイコンをクリックします。これらの 2 つのターミナル ウィンドウを切り替えます。1 つ目は関数をサービングするためのもので、2 つ目は curl を使用して関数を呼び出すためのものです。

bceb65f366d837ae.png

プルダウンを使用して、ターミナル ウィンドウを切り替えることができます。ターミナル ウィンドウが現在関数を処理している場合、プルダウン リストではその関数が node として参照されます。それ以外の場合は、zsh(または使用しているシェル)を参照します。

2 番目のターミナル ウィンドウで、次のコマンドを実行して、validateTemperature 関数を提供するローカル サーバーに温度ペイロード 50 を送信します。

curl -X POST http://localhost:8080 -H "Content-Type:application/json"  -d '{"temp":"50"}'

クラウド関数から次のレスポンスが返されます。

Temperature OK

2 番目のターミナル ウィンドウで、次のように「高すぎる」温度ペイロードを送信して、関数をもう一度テストします。

curl -X POST http://localhost:8080 -H "Content-Type:application/json"  -d '{"temp":"120"}'

クラウド関数から次のレスポンスが返されます。

Too hot

最後に、ペイロードなしで関数を呼び出してテストします。

curl -X POST http://localhost:8080

クラウド関数から次のレスポンスが返されます。

Too hot

理想的には、温度が指定されていない場合は「too hot」を返さないようにします。コードにバグが見つかりました。

関数を提供する最初のターミナル ウィンドウで Ctrl + C を押して、関数の実行を停止してください。

5. ローカルマシンから HTTP 関数をデバッグする

Visual Studio Code でコマンド パレットを開きます。Mac をお使いの場合は、Cmd + Shift + P を使用します。Windows を使用している場合は、Ctrl + Shift + P. を使用します。

コマンド パレットに「auto attach」と入力し、リストの最上位の項目を選択します。

601e542b4ec9f6f9.png

この Codelab では、下の図に示すように Only With Flag を選択します。

b9e6b762d150e62b.png

次に、VS Code で関数をサーブするために使用したターミナル ウィンドウを再読み込みします。これを行うには、右端に表示される警告アイコンにカーソルを合わせます。

[Relaunch Terminal] をクリックします。

37b61e3fb546fc76.png

再読み込みされたターミナル ウィンドウで、次のコマンドを使用して関数フレームワークを再実行し、関数をサーブします。

node --inspect node_modules/.bin/functions-framework --target=validateTemperature

ここで、--inspect フラグは、デバッグ クライアントをリッスンするように Node.js に指示します。詳細については、デバッグに関する Node のドキュメントをご覧ください。

node_modules/@google-cloud/functions-framework ではなく、node_modules/.bin/functions-framework を使用していることに注意してください。インスペクト モードを使用するには、/node_modules/.bin にある自動的にシンボリック リンクされた実行可能ファイルを使用する必要があります。

今回は、デバッガがアタッチされていることを示すオレンジ色のステータスバーが VS Code に表示されます。

行番号の左側のマージン内をクリックして、3 行目にブレークポイントを設定します。

2fbb4d5916e1dbfa.png

ブレークポイント アイコンが明るい赤色に点灯し、このコード行がデバッガからアクセス可能であることを示します。

846e6c5993cc87f9.png

2 番目のターミナル ウィンドウで、次の curl コマンドを実行してブレークポイントにヒットさせます。

curl -X POST http://localhost:8080 

3 行目が黄色でハイライト表示されます。このハイライトは、この行がデバッガによって現在評価されているステートメントであることを示します。

206c7ed1eb189e90.png

リクエストで温度ペイロードが提供されていないため、温度変数にカーソルを合わせて、その内容が undefined であることを確認します。

97979025f4bf2842.png

ステップオーバー アイコンをクリックして、次のステートメントを実行します。

現在のステートメントが if ステートメントの else 部分にジャンプします。

cf0e8ce7e0388f98.png

このデモでは、仕様で温度の読み取り値を送信することがすべてのリクエストで求められていると想定できます。温度の測定値が提供されない可能性は低いですが、その場合は関数が例外をスローする必要があります。

[切断] ボタンをクリックしてデバッガを切断します。

1070d059775ad769.png

1 つ目のターミナル ウィンドウで、Ctrl + C を押して、実行中の関数からのサービングを停止します。

次のように、温度が未定義の場合に例外をスローする if ステートメントを追加するように関数を更新します。

exports.validateTemperature = async (req, res) => {

 try {

   // add this if statement below line #2
   if (!req.body.temp) {
     throw "Temperature is undefined";
   }

 ...

最初のターミナル ウィンドウで、次のコマンドを–inspect フラグなしで実行して、クラウド関数の実行を再開します。これにより、デバッガがアタッチされなくなります。

node node_modules/@google-cloud/functions-framework --target=validateTemperature

2 番目のターミナル ウィンドウで次のコマンドを実行して、例外がスローされることを確認します。

curl -X POST http://localhost:8080 

リクエストから次の出力が返されます。

Temperature is undefined

最初のターミナル ウィンドウには、関数によって記録されたエラーも表示されます。

Serving function...
Function: validateTemperature
URL: http://localhost:8080/
got error:  Temperature is undefined

最初のターミナル ウィンドウで Ctrl+C キーを押すと、関数の実行を停止できます。

6. ローカルマシンから Google Cloud に HTTP 関数をデプロイする

ローカルマシンで Cloud Functions を作成、テスト、デバッグしたので、Google Cloud にデプロイする準備が整いました。

次のコマンドを実行して、ステップ 2 で作成したプロジェクトをローカルで使用していることを確認します。

gcloud config get-value project

ステップ 2 で指定したプロジェクトがアクティブな構成でない場合は、次のコマンドを実行します。

gcloud config set project <project-name-created-step-2>

任意のターミナル ウィンドウで、次のコマンドを実行します。

gcloud functions deploy validateTemperature --trigger-http --runtime nodejs12 --allow-unauthenticated

パラメータは次のとおりです。

  • deploy validateTemperature - 名前が validateTemperature の Cloud Functions をデプロイする gcloud サブコマンド。エントリ ポイントの名前は validateTemperature です。
  • --trigger-http - トリガー イベントのタイプ
  • --runtime nodejs12 - この関数のターゲット ランタイム
  • --allow-unauthenticated - 関数を呼び出すための公開アクセスを許可します

Cloud Functions API を有効にするよう求められます。「y」と入力して API を有効にします。

API [cloudfunctions.googleapis.com] not enabled on project 
[1057316433766]. Would you like to enable and retry (this will take a 
few minutes)? (y/N)? y 

デプロイが完了すると、出力に次の内容が表示されます。

Deploying function (may take a while - up to 2 minutes)...done. 
availableMemoryMb: 256
buildId: <your-build-id>
entryPoint: validateTemperature
httpsTrigger:
  url: https://<your-region-and-project>.cloudfunctions.net/validateTemperature
...

ターミナル ウィンドウで、curl を使用してこのパブリック エンドポイントを呼び出します。

curl -X POST https://<your-region-and-project>.cloudfunctions.net/validateTemperature -H "Content-Type:application/json"  -d '{"temp":"50"}'

適切なレスポンスを確認して、Cloud Functions の関数が正常にデプロイされたことを確認します。

Temperature OK

7. クリーンアップ

誤って課金されないようにするには(この Cloud Functions の関数が、無料枠の毎月の Cloud Functions の呼び出し割り当てを超えて誤って呼び出されるなど)、Cloud Functions の関数を削除するか、ステップ 2 で作成したプロジェクトを削除します。

Cloud Functions を削除するには、Cloud Functions Cloud コンソール(https://console.cloud.google.com/functions/)に移動します。ステップ 2 で作成したプロジェクトが現在選択されているプロジェクトであることを確認します。

ステップ 6 でデプロイした validateTemperature 関数を選択します。[削除] をクリックします。

4dada486485a935a.png

プロジェクト全体を削除する場合は、https://console.cloud.google.com/cloud-resource-manager に移動し、ステップ 2 で作成したプロジェクトを選択して、[削除] を選択します。プロジェクトを削除した場合は、Cloud SDK でプロジェクトを変更する必要があります。使用可能なすべてのプロジェクトのリストを表示するには、gcloud projects list を実行します。

8. 完了

以上で、この Codelab は完了です。Cloud Functions で Node.js ランタイムがサポートされる仕組みと、Cloud Functions でローカル デバッグが機能する仕組みについて学習する。

学習した内容

  • Functions Framework for Node.js。
  • HTTP Cloud Functions の関数を作成してローカルでテストする。
  • ローカルマシンから HTTP 関数をデバッグします。
  • ローカルマシンから HTTP 関数をデプロイします。