HTTP リクエスト経由で関数を呼び出す


functions.https を使用すると、HTTP リクエストで関数をトリガーできます。これにより、サポートされている HTTP メソッド(GETPOSTPUTDELETEOPTIONS)を使って同期関数を呼び出すことができます。

このページの例は、HTTP GET リクエストを関数のエンドポイントに送信したときにトリガーされるサンプル関数に基づいています。このサンプル関数では現在のサーバー時間を取得し、URL クエリ パラメータの指定に従って形式設定したうえで、結果を HTTP レスポンスで送信しています。

HTTP リクエストで関数をトリガーする

functions.https を使用して、HTTP イベントを処理する関数を作成します。HTTP 関数のイベント ハンドラは onRequest() イベントをリッスンします。このイベントは、Express ウェブ フレームワークによって管理されるルーターとアプリをサポートします。

Express の Request オブジェクトと Response オブジェクトの使用

onRequest() の引数として Request オブジェクトを使用すると、クライアントから送信された HTTP リクエストのプロパティにアクセスできます。Response オブジェクトを使用すると、クライアントにレスポンスを返すことができます。

exports.date = functions.https.onRequest((req, res) => {
  // ...
});

Express の既存のアプリの使用

onRequest() の引数として App を使用すると、1 つの Express アプリ全体を HTTP 関数に渡すことができます。これにより、ボイラープレート コードをミドルウェアに移動することができます。次の例をご覧ください。

const express = require('express');
const cors = require('cors');

const app = express();

// Automatically allow cross-origin requests
app.use(cors({ origin: true }));

// Add middleware to authenticate requests
app.use(myMiddleware);

// build multiple CRUD interfaces:
app.get('/:id', (req, res) => res.send(Widgets.getById(req.params.id)));
app.post('/', (req, res) => res.send(Widgets.create()));
app.put('/:id', (req, res) => res.send(Widgets.update(req.params.id, req.body)));
app.delete('/:id', (req, res) => res.send(Widgets.delete(req.params.id)));
app.get('/', (req, res) => res.send(Widgets.list()));

// Expose Express API as a single Cloud Function:
exports.widgets = functions.https.onRequest(app);

HTTP 関数の呼び出し

HTTP 関数はデプロイ後、その独自の一意な URL を使って呼び出すことができます。URL は次の要素で構成されます(順番は記載順)。

  • 関数のデプロイ場所となった 1 つ以上のリージョン。本番環境の関数では、ネットワーク レイテンシを最小限にするために、ロケーションの明示的な設定が必要になる場合があります。
  • Firebase プロジェクト ID
  • cloudfunctions.net
  • 関数の名前

たとえば、date() を呼び出す URL は次のようになります。

https://us-central1-<project-id>.cloudfunctions.net/date

関数のデプロイ時に権限エラーが発生した場合は、デプロイ コマンドを実行するユーザーに適切な IAM ロールが割り当てられていることを確認します。

Express アプリのルーティングでは、定義したアプリの URL パスに関数名が接頭辞として追加されます。たとえば、上記の Express アプリの例でゲッターを呼び出す URL は次のようになります。

https://us-central1-<project-id>.cloudfunctions.net/widgets/<id>

ファイアウォールまたは IP フィルタの背後で HTTP 関数を呼び出す場合は、HTTP 関数の処理用に Google で使用される IP アドレスを検索することができます。

Cloud Functions でのミドルウェア モジュールの使用

Cookie サポートや CORS などのミドルウェア依存関係を注入する必要がある場合は、関数内でこれらを呼び出します。たとえば、CORS サポートを有効にするには、次のブロックを追加します。

// Enable CORS using the `cors` express middleware.
cors(req, res, () => {
  // ...
});

リクエストからの値の読み込み

次の表に、共通のシナリオを示します。

コンテンツ タイプ リクエストの本文 動作
application/json '{"name":"John"}' request.body.name =「John」となります
application/octet-stream 'my text' request.body =「6d792074657874」となります(リクエストの RAW バイト。Node.js バッファ ドキュメントを参照)
text/plain 'my text' request.body =「my text」となります
application/x-www-form-urlencoded 'name=John' request.body.name =「John」となります

次のボディパーサーにより解析が行われます。

次のリクエストにより関数が呼び出される場合を考えてみましょう。

curl -X POST -H "Content-Type:application/json" -H "X-MyHeader: 123" YOUR_HTTP_TRIGGER_ENDPOINT?foo=baz -d '{"text":"something"}'

送信されたデータは次の条件で実行されます。

プロパティ / メソッド
req.method "POST"
req.get('x-myheader') "123"
req.query.foo "baz"
req.body.text "something"
req.rawBody リクエストの RAW(未解析の)バイト数

date() 関数の例では、この関数は URL パラメータと本文の両方を format 値に対してテストし、使用する日時形式を設定します。

let format = req.query.format;
format = req.body.format;

HTTP 関数の終了

必ず send()redirect()、または end() を使用して HTTP 関数を終了してください。そうしないと、関数は引き続き実行され、システムによって強制終了される可能性があります。同期、非同期、Promise もご覧ください。

Node.js の moment モジュールによりサーバー時間を取得して形式を設定した後、その結果を HTTP レスポンスとして送信してdate() 関数を終了します。

const formattedDate = moment().format(`${format}`);
functions.logger.log('Sending Formatted date:', formattedDate);
res.status(200).send(formattedDate);

Firebase Hosting への HTTP 関数の接続

HTTP 関数を Firebase Hosting に接続できます。Firebase Hosting サイトでのリクエストを特定の HTTP 関数にプロキシできます。これにより、独自のカスタム ドメインを HTTP 関数とともに使用することもできます。詳しくは、Firebase Hosting への Cloud Functions の接続についてのドキュメントをご覧ください。