Cloud Functions を使用した動的コンテンツの配信とマイクロサービスのホスティング

Cloud Functions と Firebase Hosting を組み合わせれば、動的コンテンツを生成して配信できるほか、REST API をマイクロサービスとしてビルドすることもできます。

Cloud Functions for Firebase を使用すると、HTTPS リクエストに応じて、バックエンド コードを自動的に実行できます。コードは Google のクラウドに保存され、マネージド環境で実行されます。独自のサーバーを管理およびスケーリングする必要はありません。

Cloud Functions と Firebase Hosting の統合の導入事例については、サーバーレスの概要をご覧ください。

Cloud Functions を Firebase Hosting に接続する

このセクションでは、Firebase Hosting と関数を接続する例について説明します。

動的コンテンツの配信パフォーマンスを向上させるために、必要に応じてキャッシュ設定を調整できます。

ステップ 1: Cloud Functions を設定する

  1. Firebase CLI の最新バージョンを使用していること、Firebase Hosting が初期化されていることを確認します。

    CLI のインストールと Hosting の初期化の詳細については、Hosting のスタートガイドをご覧ください。

  2. Cloud Functions の設定が完了していることを確認します。

    • Cloud Functions をすでに設定している場合は、ステップ 2: HTTPS 関数を作成してテストするに進みます。

    • Cloud Functions をまだ設定していない場合は、次の操作を行います。

      1. プロジェクト ディレクトリのルートから次のコマンドを実行して Cloud Functions を初期化します。

        firebase init functions
      2. メッセージが表示されたら、JavaScript を選択します(ここでは JS を使用しています)。

      3. ローカル プロジェクト ディレクトリに functions ディレクトリがあることを確認します(このディレクトリは実行した Firebase コマンドによって作成されます)。この functions ディレクトリに Cloud Functions のコードが保存されます。

ステップ 2: Hosting サイトの HTTPS 関数を作成してテストする

  1. 任意のエディタで /functions/index.js を開きます。

  2. ファイルの内容を次のコードで置き換えます。

    このコードは、1 時間ごとに BONG で HTTPS リクエストに応答する HTTPS 関数(bigben)を作成します。

    const functions = require('firebase-functions');
    
    exports.bigben = functions.https.onRequest((req, res) => {
      const hours = (new Date().getHours() % 12) + 1  // London is UTC + 1hr;
      res.status(200).send(`<!doctype html>
        <head>
          <title>Time</title>
        </head>
        <body>
          ${'BONG '.repeat(hours)}
        </body>
      </html>`);
    });
    
  3. Firebase Local Emulator Suite を使用してローカルで関数をテストします。

    1. ローカル プロジェクト ディレクトリのルートから次のコマンドを実行します。

      firebase emulators:start
    2. CLI から返されたローカル URL(例: http://localhost:5001/PROJECT_ID/us-central1/bigben)で関数にアクセスします。

HTTPS リクエストの詳細については、Cloud Functions のドキュメントをご覧ください。

次のステップでは、この HTTPS 関数に Firebase Hosting URL からアクセスして、Firebase でホストされているサイトの動的コンテンツを生成できるようにします。

ステップ 3: 関数に HTTPS リクエストを送信する

rewrite ルールを使用して、特定のパターンに一致するリクエストを単一の宛先に向けることができます。次の手順では、Hosting サイトのパス ../bigben からすべてのリクエストを送信して bigben 関数を実行する方法を示します。

  1. firebase.json ファイルを開きます。

  2. hosting セクションに次の rewrite 構成を追加します。

    "hosting": {
      // ...
    
      // Add the "rewrites" attribute within "hosting"
      "rewrites": [ {
        "source": "/bigben",
        "function": {
          "functionId": "bigben",
          "region": "us-central1"  // optional (see note below)
          "pinTag": true           // optional (see note below)
        }
      } ]
    }
    
  3. Firebase エミュレータで再度テストして、リダイレクトが想定どおり動作することを確認します。

    1. ローカル プロジェクト ディレクトリのルートから次のコマンドを実行します。

      firebase emulators:start
    2. CLI によって返される、ローカルでホストされるサイトの URL(通常は localhost:5000)にアクセスします。ただし、http://localhost:5000/bigben のように URL に bigben を追加します。

  4. そのサイトの関数と機能をイテレーションします。Firebase エミュレータを使用して、このイテレーションをテストします。

最適なパフォーマンスを得るには、次のいずれかのリージョンを選択して、関数を Hosting と同じ場所に配置します。

  • us-west1
  • us-central1
  • us-east1
  • europe-west1
  • asia-east1

リライトルールの詳細については、Hosting 構成ページをご覧ください。さまざまな Hosting 構成のレスポンスの優先順位についての説明もあります。

動的コンテンツの配信パフォーマンスを向上させるために、必要に応じてキャッシュ設定を調整できます。

ステップ 4: 関数をデプロイする

エミュレータで関数が意図したとおりに動作するようになったら、実際のプロジェクト リソースを使用してデプロイ、テスト、実行に進むことができます。この段階で、本番環境で実行されている関数のスケーリング動作を制御するためのランタイム オプションの設定を検討することをおすすめします。

  1. ローカル プロジェクト ディレクトリのルートから次のコマンドを実行して、関数および Hosting のコンテンツと構成をサイトにデプロイします。

    firebase deploy --only functions,hosting
  2. 次の URL で公開サイトと関数にアクセスします。

    • Firebase のサブドメイン:
      PROJECT_ID.web.app/bigbenPROJECT_ID.firebaseapp.com/bigben

    • 接続されたカスタム ドメイン:
      CUSTOM_DOMAIN/bigben

ウェブ フレームワークを使用する

Cloud Functions で Express.js などのウェブ フレームワークを使用してアプリの動的コンテンツを提供すると、複雑なウェブアプリをより簡単に作成できるようになります。

次のセクションでは、Firebase Hosting と Cloud Functions とを組み合わせて Express.js を使用する例を示します。

  1. functions ディレクトリから次のコマンドを実行して、ローカル プロジェクトに Express.js をインストールします。

    npm install express --save
  2. /functions/index.js ファイルを開き、Express.js をインポートして初期化します。

    const functions = require('firebase-functions');
    const express = require('express');
    const app = express();
    
  3. 次の 2 つのエンドポイントを追加します。

    1. 最初のエンドポイントを追加して、/ にウェブサイトのインデックスを追加します。

      app.get('/', (req, res) => {
        const date = new Date();
        const hours = (date.getHours() % 12) + 1;  // London is UTC + 1hr;
        res.send(`
          <!doctype html>
          <head>
            <title>Time</title>
            <link rel="stylesheet" href="/style.css">
            <script src="/script.js"></script>
          </head>
          <body>
            <p>In London, the clock strikes:
              <span id="bongs">${'BONG '.repeat(hours)}</span></p>
            <button onClick="refresh(this)">Refresh</button>
          </body>
        </html>`);
      });
      
    2. API として BONG カウントを JSON 形式で返す別のエンドポイントを /api に追加します。

      app.get('/api', (req, res) => {
        const date = new Date();
        const hours = (date.getHours() % 12) + 1;  // London is UTC + 1hr;
        res.json({bongs: 'BONG '.repeat(hours)});
      });
      
  4. Express.js アプリを HTTPS 関数としてエクスポートします。

    exports.app = functions.https.onRequest(app);
    
  5. firebase.json ファイルで、すべてのリクエストを app 関数に送信します。この rewrite により、構成済みの別のサブパス(この例では //api)を Express.js で処理できるようになります。

    {
     "hosting": {
       // ...
    
       // Add the "rewrites" attribute within "hosting"
       "rewrites": [ {
         "source": "**",
         "function": "app"
       } ]
     }
    }
    

ミドルウェアを追加する

説明を続けましょう。ここでは Express.js を使用しているので、Express.js ミドルウェアを通常の方法で追加できます。たとえば、エンドポイントで CORS リクエストを有効にできます。

  1. 次のコマンドで cors ミドルウェアをインストールします。

    npm install --save cors
  2. /functions/index.js ファイルを開き、次のように cors を Express.js アプリに追加します。

    const cors = require('cors')({origin: true});
    app.use(cors);
    

Express アプリとミドルウェア モジュールで Firebase を使用する方法については、Cloud Functions のドキュメントをご覧ください。

次のステップ