【GCP入門編・第14回】 Cloud Functions を使ってサーバレスアーキテクチャを体験しよう!

GCP

投稿日:2018/02/14

これまでの Web アプリケーションの構築では、 Ruby on Rails や Django などの、モノリシックな MVC フレームワークを用いた開発が一般的でした。しかしここ数年で、単機能の API サーバーを組み合わせて複雑なシステムを構築するマイクロサービスという考え方が広まりました。
フロントエンドが HTML + JavaScript で実装され、バックエンドの API サーバーにリクエストすることでデータの永続化やビジネスロジックの実行を行う場合、 アプリケーションサーバーは HTML テンプレートのレンダリングなどを行う必要はありません。こうした考え方を突き詰めていった結果、 アプリケーションサーバーを必要としないサーバーレスアーキテクチャという考え方が生まれてきました。
この考え方に基づき、 AWS が Lambda という JavaScript で書かれた関数をクラウド上で動作させるサービスを提供し始めました。これに答える形で、 GCP でも単純な関数をクラウド上で実行する Cloud Functions というサービスが開始されました。
この記事では、 Cloud Functions について説明し、実際に動作する関数を Cloud Functions 上に配置するデモを行います。

この記事の目的

  • Cloud Functions とは何かを理解しよう。
  • Cloud Functions を実際に使ってみよう。

Cloud Functions とは

Cloud Functions は、 GCP 上で JavaScript で書かれた関数を実行するためのサービスです。関数はイベントベースで発火する形式になっており、 Google Cloud Storage もしくは Google Cloud Pub/Sub からのイベントで呼び出されます。また、 HTTP リクエスト経由での実行も可能となっています。 JavaScript ランタイムとしては Node.js を使用しており、自動的にスケールする仕組みとなっています。

Cloud Functions を使ってみよう

それでは早速、試用してみましょう。まず、手元のターミナルを開き、 gcloud コマンドで alpha component をインストールします。

$ gcloud components install beta

01.png
続けるかどうか質問されますので、 Y を押してインストールを行います。
インストールが完了したら、 Cloud Functions をデプロイするための準備を行います。 Cloud Functions は Google Cloud Storage のバケットを使ってデプロイします。次のコマンドで、バケットの作成を行いましょう。

$ gsutil mb gs://test-cloud-functions-xxx

01.png
Google Cloud Storage のバケットの名前は世界で一意である必要があります。そこで、他のバケットとコンフリクトしないよう、xxxにはお好きな数字を入れます。
次に、ローカル環境で gcf_test という名前でフォルダを作成します。このフォルダは作業のためのフォルダとなります。

$ mkdir gcf_test
$ cd gcf_test

ここに、 index.js という名前で以下のファイルを作成します。

exports.helloGET = function helloGET (req, res) {
  res.send('Hello Google Cloud Functions!');
};

リクエストに対して、単純にメッセージを返す関数です。保存できたら、 Cloud Functions をデプロイします。

$ gcloud alpha functions deploy helloGET --stage-bucket test-cloud-functions-xxx --trigger-http

–trigger-http オプションは HTTP リクエストで関数が実行されるようにするフラグです。
デプロイが完了したら、以下のように curl で関数を実行してみましょう。

curl "https://[リージョン名]-[プロジェクトID].cloudfunctions.net/helloGET"

プロジェクト ID にはご自分がお使いのプロジェクト ID を、リージョンには asia-northeast1-a を入力します。以下のような URL となるでしょう。
https://asia-northeast1-a-sunnycall316.cloudfunctions.net/helloGET
curl の結果、 ”Hello Google Cloud Functions!” というメッセージが表示されれば成功です。

Cloud Functions で Cloud Datastore のデータを読む

次に、 Cloud Functions から Cloud Datastore のデータを読み込み、表示をする Function を作成してみましょう。
先ほどのフォルダとは別に、ローカル環境に作業のためのフォルダを作成します。この例では gcf_datastore_test としました。

$ mkdir gcf_dastastore_test
$ cd gcf_datastore_test

今回のサンプルでは依存モジュールとして google-cloud/datastore モジュールを使用します。そのため、package.json で依存モジュールの宣言を行っておく必要があります。 npm init コマンドを使って、 package.json を作成しましょう。 name や version , description など、入力する項目は全てデフォルトのままで問題ありません。

$ npm init .

03.png
エディタで package.json を開き、依存モジュールを追加します。 追加後の package.json は以下のようになっているでしょう。

{
  "name": "datastore_sample",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "dependencies": {
    "@google-cloud/datastore": "1.1.0"
  },
  "devDependencies": {},
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

依存モジュールの宣言を行ったら、npm install コマンドで依存モジュールをインストールします。

$ npm install

04.png
先ほどと同様に、 index.js ファイルを作成します。今回は、 Datastore ライブラリを使って、以下のように entryGET 関数を定義します。

const Datastore = require('@google-cloud/datastore');
const datastore = Datastore();
exports.entryGET = function entryGET (req, res) {
   const key = datastore.key([requestData.kind, requestData.key]);
   return datastore.get(key)
     .then(([entity]) => {
       res.status(200).send(entity);
     });
};

Cloud Functions をデプロイします。デプロイ先は先ほど使用したバケットと同じものを使います。

$ gcloud alpha functions deploy entryGET --stage-bucket test-cloud-functions-xxx --trigger-http

07
デモに使用するため、 Datastore にエンティティを追加します。ブラウザを開いて、 GCP の Web コンソールに移動し、 左側のメニューから Datastore を選択します。
[CREATE ENTITY] をクリックし、エンティティの作成画面に移動します。
以下の画像のように、 Kind を “User” , Property として、 “name” を “John” と入力します。
[Create] をクリックすると、エンティティが保存されます。
05
次に、デモを行う際に必要となる Key Identifier を控えておきます。 エンティティの一覧画面の Name/ID 列に書かれているのが Key Identifier となります。 下の画面の場合は 5629499534213120 です。
06
それでは、 Kind と Key を使って、Cloud Functions 経由で Cloud Datastore のエンティティを表示します。以下のコマンドを実行すると、エンティティが表示されます。

$ curl -H "Content-Type: application/json" -X POST \
       -d '{"kind":"User","key": [Key Identifier]}' \
       "https://[リージョン名]-[プロジェクトID].cloudfunctions.net/entryGET"

このように、 Cloud Functions で Cloud Datastore の読み書きが行えます。この機能を使うことで、データベースが必要な処理も Cloud Functions で実現できることがわかるでしょう。

おわりに

いかがでしたか。かなり単純な例であるため Cloud Functions の強力さはいまいち実感できないかもしれません。ただ、フロントエンド側が HTML と JavaScript で書かれており、バックエンドはすべて Cloud Functions になっていると想像すると、これまで通常だったようにバックエンドのサーバーを Python や Ruby で書くよりも、より高速な開発が行えます。
サーバーレスアーキテクチャは、まだ生まれたばかりの考え方であり、今すぐに一般的になるという訳ではないでしょうが、将来の Web サービスの開発方法を考えながら Cloud Functions を試用してみるのもいいのではないでしょうか。

同じシリーズの記事

GCP のメリットを最大限に活用しよう!

GCP・G Suite のご相談・
お見積り依頼はお気軽に
TEL.03-5840-8815
お問合せフォーム TEL.03-5840-8815