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

1. 概要

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

JavaScript で記述された Cloud Functions 関数は、Google Cloud Platform の Node.js 環境で実行されます。任意の標準 Node.js ランタイムで Cloud Functions の関数を実行して、移植性とローカルテストを実現できます。

チュートリアル

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

学習内容

  • Node.js 用の Functions Framework。
  • 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 は、Google Cloud Functions チームが提供する、ポータブルな Node.js 関数を記述するためのオープンソースの FaaS(Function as a Service)フレームワークです。

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

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

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

npm init

デフォルトを受け入れる場合でも、アプリのエントリ ポイントとして index.js を使用してください。

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

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/

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

bceb65f366d837ae.png

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

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

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

Cloud Functions から次のようなレスポンスが返されます。

Temperature OK

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

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

Cloud Functions から次のようなレスポンスが返されます。

Too hot

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

curl -X POST http://localhost:8080

Cloud Functions から次のようなレスポンスが返されます。

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

再読み込みしたターミナル ウィンドウで、次のコマンドを使用して Functions Framework を再実行し、関数を処理します。

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

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

97979025f4bf2842.png

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

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

cf0e8ce7e0388f98.png

このデモでは、すべてのリクエストで温度測定値を送信することが仕様に規定されていると仮定します。温度測定値が指定されていない場合、関数は例外をスローする必要があります。

[切断] ボタンをクリックして、デバッガの接続を解除します。

1070d059775ad769.png

最初のターミナル ウィンドウで、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 フラグなしで次のコマンドを実行して、デバッガの接続を回避し、Cloud Functions の実行を再開します。

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 関数を validateTemperature という名前のエンドポイントでデプロイする gcloud サブコマンド
  • --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 関数が 無料 tier の 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 でのローカル デバッグの動作をご覧ください。

学習した内容

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