Cloud Functions ローカル環境 httpリクエスト
Cloud Functionsのローカル環境を構築するチュートリアルにトライしてみました。
そのままトライするのではなく、チュートリアルのアプリはhttpリクエストに対してhellow worldを返すだけですが、アプリ内でhttpリクエストを行い、結果を返すアプリに変更してみます。
Cloud Functionsのプログラムはnodejsで作ります。
リファレンス
nodejsのインストール
Cloud Functionsはいろいろな言語で開発できますが、ここではnodejsを使用します。
以下からインストーラをダウンロードして実行します。
https://nodejs.org/en/download
dockerのインストール
Cloud Functionsは結局のところコンテナで実行されるアプリです。dockerを使用します。
以下の手順に沿ってインストールします。
https://docs.docker.com/desktop/install/windows-install/#install-docker-desktop-on-windows
日本版のサイトもあります。
https://docs.docker.jp/desktop/install/windows-install.html#id4
packのインストール
dockerイメージをビルドするツールです。dockerだけでもimageのビルドが可能だと思いますが、packを使うことでdockerfileの記述が不要になります。
https://buildpacks.io/docs/for-platform-operators/how-to/integrate-ci/pack/
chocolateのインストール
Windowsでpackをインストールする場合、上記の公式サイトにいくつか方法が記載されていますが、ここではchocolateを使用します。
chocolateはwindowsでのパッケージ管理ツールの一つのようです。以下のコマンドでインストールできます。
# 管理者権限で実行
Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
chocolateでpackをインストール
以下のコマンドでインストールできます。
# 管理者権限で実行
choco install pack --version=0.33.2
チュートリアルアプリの作成
公式の手順通りです。
チュートリアルアプリのimageをビルドしてコンテナを実行
公式の手順通りです。
http://localhost:8080/にアクセスしてhello worldが表示されたらOKです。
補足
imageの作成はpowershellだと以下のコマンドになります。
pack build `
--builder gcr.io/buildpacks/builder:v1 `
--env GOOGLE_FUNCTION_SIGNATURE_TYPE=http `
--env GOOGLE_FUNCTION_TARGET=helloWorld `
my-first-function
以下のようにイメージが作成されます。
※image内の容量が足りないと”Timer: Saving index.docker.io/library/my-first-function:latest…“で止まります。
チュートリアルアプリの修正
hello worldを返すだけでしたが、httpリクエストを送信して、クライアントにその結果を返す処理に修正します。
index.jsを更新
Cloud Functionsでhttpリクエストを送信するサンプルコードが公式であります。これをベースにします。
まず、index.jsにコピペします。
次に以下の4点を修正します。
- index.js
- urlを修正します。私は簡単なjsonを返してくれるサイト見つけて、そのurlにしました。
- httpリクエストに成功したら、bodyをテキストで返すように修正します。
- package.json
- scripts startの関数名を”helloWorld”から”makeRequest”に変更します。
- docker imageのビルドコマンドのGOOGLE_FUNCTION_TARGETも”helloWorld”から”makeRequest”に変更します。
index.jsは以下のようになりました。
const fetch = require('node-fetch');
const functions = require('@google-cloud/functions-framework');
/**
* HTTP Cloud Function that makes an HTTP request
*
* @param {Object} req Cloud Function request context.
* @param {Object} res Cloud Function response context.
*/
functions.http('makeRequest', async (req, res) => {
const url = 'http://ip.jsontest.com/'; // URL to send the request to
const externalRes = await fetch(url);
if(!externalRes.ok){
res.send("error");
return;
}
const body = await externalRes.text();
res.send(body);
});
変更したimageのビルドコマンドです。
pack build `
--builder gcr.io/buildpacks/builder:v1 `
--env GOOGLE_FUNCTION_SIGNATURE_TYPE=http `
--env GOOGLE_FUNCTION_TARGET=makeRequest `
my-first-function
packageを更新
サンプルコードでnode-fetchというモジュールを使用していますので、npmインストールします。node-fetchはv2系を指定します。requireでインポートできないためです。
npm install node-fetch@2
コードの修正は以上です。イメージをビルドしてコンテナを実行してhttp://localhost:8080/にアクセスすると、直接http://ip.jsontest.com/にアクセスしたときと同じ内容が表示されるはずです。
※コンテナを実行するコマンド
docker run --rm -p 8080:8080 my-first-function