使用Edge函数构建API端点

IMPORTANT
AEM Edge函数当前为测试版。 功能和文档可能会更改。 如需反馈,请联系aemcs-edgecompute-feedback@adobe.com

AEM Edge函数是在Adobe CDN(Fastly Compute)上运行的JavaScript模块。 通过将CDN源选择器规则与代码中的提取事件处理程序配对,可将其公开为​一个或多个 HTTP端点。

本页介绍合同和关键文件。 您可以在处理程序中编写任何逻辑,包括对其他系统的出站fetch()调用。 保持处理程序快速且短暂可用,以使其适合边缘运行时。

先决条件

  • 基于样板模板的AEM Edge函数项目
  • 已安装Adobe Edge Functions插件的AEM CLI

对于首次设置,请参阅在AEM as a Cloud Service上设置在Edge Delivery Services上设置

HTTP请求如何到达您的代码

请求将通过两个步骤到达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函数名称和可选的configssecretskvs
代码
src/index.js
匹配路由、运行处理程序逻辑并返回Response

原始选择器和函数名称必须对齐。 如果edgeFunctions.yaml声明my-edge-function,则原始选择器在cdn.yaml中使用edgefunction-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-my-route-to-edge-function # logical name for the origin selector rule
        when: { reqProperty: path, equals: "/my-route" } # 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中都需要各自的原始选择器规则。 一个AEM Edge函数可以提供多条路由,但CDN必须将每条路径路由到该函数。 将skipCache: false设置为允许CDN缓存以实现稳定响应,或将skipCache: true设置为绕过CDN缓存以实现动态或个性化响应。

有关原始选择器选项,请参阅原始选择器

处理请求

每个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 {
    // route matching
    if (url.pathname === "/my-route" && 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 routes here

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

要点:

概念
详细信息
入口点
addEventListener("fetch", ...)将每个请求连接到您的提取事件处理程序,请参阅FetchEvent.responseWith
请求
event.request是标准提取API Request(方法、URL、标头、正文),请参阅请求引用
响应
返回new Response(body, { status, headers })以控制状态、内容类型和缓存标头,请参阅响应引用
路由匹配
匹配url.pathname、HTTP方法、标头或handleRequest中的查询参数
客户端元数据
event.client公开连接详细信息,如客户端IP地址,请参阅FetchEvent.client

路由匹配存在于index.js中。 随着路由的增长,请将处理程序逻辑移动到单独的文件中并导入它们,如上面的示例中的my-api.js所示。

编写处理程序逻辑

在每条路由内,可以运行任何适合边缘运行时的JavaScript。 保持工作快速且短命。 与长时间运行或计算量大的计算相比,偏向于轻量级转换、地域查找、简单的JSON或HTML响应以及小型聚合。

最低响应如下所示:

if (url.pathname === "/my-route" && 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函数中的缓存

更多代码示例

有关完整的工作示例,请参阅AEM Edge函数样板

示例
文件
它显示的内容
简单响应
src/index.js
路由匹配和处理程序中内置的响应
外部API
src/weather.js
地理位置查找加上叫客fetch()

后续步骤

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