Edge Functionsを使用したAPI エンドポイントの構築

IMPORTANT
AEM Edge Functionsは現在ベータ版です。 機能やドキュメントは変更される可能性があります。 フィードバックについては、aemcs-edgecompute-feedback@adobe.comまでお問い合わせください。

AEM Edge関数は、Adobe CDN (Fastly Compute)で実行されるJavaScript モジュールです。 コード内のフェッチ イベント ハンドラーとCDN オリジン セレクターのルールを組み合わせることで、1つ以上の HTTP エンドポイントとして公開します。

このページでは、契約とキーファイルについて説明します。 他のシステムへのアウトバウンド fetch()呼び出しを含め、任意のロジックをハンドラーに記述できます。 ハンドラーを高速かつ短命に保ち、エッジランタイムに適合させます。

前提条件

初回設定については、AEM as a Cloud Serviceでの設定またはEdge Delivery Servicesでの設定を参照してください。

HTTP リクエストがコードに到達する方法

リクエストは、2つの手順でAEM Edge関数に到達します。CDN オリジン セレクターは、エンドポイントを関数にルーティングし、フェッチイベントハンドラーが実行されます。

Browser → CDN origin selector (cdn.yaml) → AEM Edge Function (index.js) → Your handler logic (optional fetch to other systems)
レイヤー
ファイル
担当
CDN
config/cdn.yaml
パスを一致させて、AEM Edge関数にリクエストを転送します
関数
config/edgeFunctions.yaml
AEM Edge関数名とオプションのconfigssecretsまたはkvsを宣言します
コード
src/index.js
エンドポイントを一致させ、ハンドラーロジックを実行し、Responseを返します

オリジン セレクターと関数名は整列する必要があります。 edgeFunctions.yamlmy-edge-functionを宣言した場合、オリジン セレクターはcdn.yamledgefunction-my-edge-functionを使用します。

# config/edgeFunctions.yaml
kind: "EdgeFunctions"
version: "1"
data:
  functions:
    - name: my-edge-function #<name-of-the-function>
# config/cdn.yaml (origin selector excerpt)
kind: 'CDN'
version: '1'
data:
  originSelectors:
    rules:
      - name: route-status-endpoint-to-edge-function # logical name for the origin selector rule
        when: { reqProperty: path, equals: "/status" } # path to match
        action:
          type: selectAemOrigin
          originName: edgefunction-my-edge-function # edgefunction-<name-of-the-function>
          skipCache: false # false to use the CDN cache for this path
      - name: route-my-api-to-edge-function # logical name for the origin selector rule
        when: { reqProperty: path, equals: "/my-api" } # path to match
        action:
          type: selectAemOrigin
          originName: edgefunction-my-edge-function # edgefunction-<name-of-the-function>
          skipCache: true # true to bypass the CDN cache for this path

各エンドポイントには、cdn.yamlに独自のオリジン セレクター規則が必要です。 1つのAEM Edge関数は複数のエンドポイントに対応できますが、CDNは各パスをその関数に転送する必要があります。 skipCache: falseを設定して、安定した応答に対するCDN キャッシュを許可するか、動的またはパーソナライズされた応答に対するCDN キャッシュをバイパスするskipCache: trueを許可します。

オリジン セレクターのオプションについては、​ オリジン セレクターを参照してください。

リクエストの処理

すべてのAEM Edge関数は、フェッチイベントハンドラーを登録します。 Adobe CDNは、一致するリクエストごとに、そのハンドラーを呼び出します。 ハンドラーは受信Requestを読み取り、ロジックを実行してResponseを返します。

// src/index.js
import { myApiHandler } from "./my-api.js";
import * as response from "./lib/response.js";

// entry point for the AEM Edge Function
addEventListener("fetch", (event) => event.respondWith(handleRequest(event)));

async function handleRequest(event) {
  // event.request is a standard Fetch API Request (method, URL, headers, body)
  const req = event.request;
  const url = new URL(req.url);

  try {
    // endpoint matching
    if (url.pathname === "/status" && req.method === "GET") {
      return new Response("OK", { status: 200 });
    } else if (url.pathname === "/my-api" && req.method === "GET") {
      return await myApiHandler(req, event.client);
    }
    // add more endpoints here

    return response.notFound();
  } catch (err) {
    console.log(err);
    return response.error();
  }
}

重要なポイント:

コンセプト
詳細
エントリポイント
addEventListener("fetch", ...)は、フェッチ イベント ハンドラーに対するすべてのリクエストをワイヤー接続します。FetchEvent.respondWithを参照してください。
リクエスト
event.requestは標準のFetch API Request (メソッド、URL、ヘッダー、本文)です。​ リクエストリファレンス ​を参照してください
応答
new Response(body, { status, headers })を返して、ステータス、コンテンツ タイプ、キャッシュ ヘッダーを制御します。応答リファレンス ​を参照してください。
Endpoint matching
handleRequest内のurl.pathname、HTTP メソッド、ヘッダー、またはクエリパラメーターに一致します
クライアントメタデータ
event.clientは、クライアント IP アドレスなどの接続の詳細を公開します。FetchEvent.clientを参照してください。

エンドポイントの一致がindex.jsに存在します。 エンドポイントが成長するにつれ、ハンドラーロジックを個別のファイルに移動してインポートします。上記の例のmy-api.jsと同様です。 API サーフェスの拡張に伴うパターンについては、Edge Functionsを使用した複数のエンドポイントの提供を参照してください。

ハンドラーロジックの記述

各エンドポイントハンドラー内では、エッジランタイムに適合する任意のJavaScriptを実行できます。 迅速かつ短期的に作業を進めます。 長期的な計算よりも、軽量な変換、位置情報の検索、シンプルなJSONやHTMLの回答、小さな集計を好みます。

最小限の応答は次のようになります。

if (url.pathname === "/status" && req.method === "GET") {
  return new Response("OK", { status: 200 });
}

JSON、HTML、プレーンテキストを返すことができます。 コンテンツの種類とキャッシュを制御するために、Responseにヘッダーを設定します。

return new Response(JSON.stringify({ status: "ok" }), {
  status: 200,
  headers: {
    "Content-Type": "application/json",
    "Cache-Control": "public, max-age=300",
  },
});

別のシステムからデータが必要な場合は、fetch()で呼び出します。 AEM Edge関数に資格情報を保持します。 クライアント JavaScriptでシークレットを公開しないでください。

// src/my-api.js
async function myApiHandler(req, client) {
  const backendRequest = new Request("https://api.example.com/data");

  // optionally, you can add headers to the request
  // backendRequest.headers.set("Authorization", `Bearer <your-access-token>`);

  const backendResponse = await fetch(backendRequest);

  if (!backendResponse.ok) {
    return new Response("Backend error", { status: 502 });
  }

  const data = await backendResponse.json();

  return new Response(JSON.stringify(data), {
    status: 200,
    headers: {
      "Content-Type": "application/json",
      "Cache-Control": "max-age=300",
    },
  });
}

export { myApiHandler };

アウトバウンド fetch()呼び出しは通常、次のパターンに従います。

  1. リクエスト(headersevent.client、Fastlyの位置情報ヘルパー)からコンテキストを派生させます。
  2. 他のシステムにRequestをビルドします。
  3. await fetch(request)を呼び出します(オプションでbackendという名前のオリジンを使用)。
  4. 応答を解析して、新しいResponseをクライアントに返します。

プラットフォームの制限が適用されます。 各呼び出しは、最大​32件のアウトバウンドフェッチ呼び出しをサポートします。 フェッチ呼び出しのキャッシュ動作については、「AEM Edge Functionsでのキャッシュ ​」を参照してください。

その他のコード例

作業例の詳細については、AEM Edge Functions ボイラープレート ​を参照してください。

ファイル
What it shows
シンプルな回答
src/index.js
ルートマッチングと、ハンドラーに組み込まれた応答
外部API
src/weather.js
位置情報とアウトバウンド fetch()

その他のリソース

recommendation-more-help
experience-manager-learn-help-cloud-service