將區塊連線至AEM Edge函式

IMPORTANT
AEM Edge功能目前仍在測試階段。 功能和檔案可能會變更。 如需意見回饋,請連絡aemcs-edgecompute-feedback@adobe.com

我們的目標是建置動態Edge Delivery Services區塊,該區塊會呼叫AEM Edge函式以從協力廠商API擷取動態資料。

第三個步驟是連線您在中建立架構的Edge Delivery Services區塊開發Edge Delivery Services區塊至您在開發AEM Edge函式中建立的AEM Edge函式。 這是將兩個專案繫結在一起的步驟。 使用兩個不同的連線埠,並排執行兩個本機開發伺服器,並根據執行位置讓區塊的JavaScript呼叫正確的伺服器。

執行兩個本機開發伺服器

在Edge Delivery Services網站專案中:

$ aem up

這在http://localhost:3000提供網站。

在AEM Edge功能專案中,在第二終端機:

$ aio aem edge-functions serve

這會提供位於http://127.0.0.1:7676的端點。

接通擷取呼叫

將下列專案新增至estimated-delivery.js,並搭配來自開發Edge Delivery Services區塊的支架。

選擇適合環境的URL

Edge Delivery Services區塊會根據其執行位置呼叫不同的URL:

環境
區塊呼叫的URL
原因
本機開發
http://127.0.0.1:7676/api/frescopa/estimated-delivery
Edge Delivery Services區塊和AEM Edge函式是位於兩個不同連線埠上的兩個獨立本機伺服器
已部署
/api/frescopa/estimated-delivery (相對)
CDN來源選擇器會將此路徑路由至網站網域上的AEM Edge函式

從瀏覽器報告的主機名稱偵測本機開發,並快取結果,讓每個請求都不會重複檢查:

// blocks/estimated-delivery/estimated-delivery.js
const API_PATH = '/api/frescopa/estimated-delivery';
const LOCAL_EDGE_FUNCTION_ORIGIN = 'http://127.0.0.1:7676';

let cachedApiUrl;

function isLocalDev() {
  const { hostname } = window.location;
  return hostname === 'localhost' || hostname === '127.0.0.1';
}

function getEstimatedDeliveryApiUrl() {
  if (cachedApiUrl) return cachedApiUrl;

  // Local: site (aem up) on :3000, Edge Function on :7676 — call it directly.
  // Production: relative path, routed to Edge Function via CDN origin selector.
  cachedApiUrl = isLocalDev()
    ? `${LOCAL_EDGE_FUNCTION_ORIGIN}${API_PATH}`
    : API_PATH;

  return cachedApiUrl;
}

這是Edge Delivery Services區塊中唯一一個環境特定邏輯。 其他所有動作,擷取呼叫、回應處理、轉譯在兩個環境中的運作方式都相同,因為路徑相同;只有來源變更。

NOTE
本機dev呼叫跨越原始專案(localhost:3000127.0.0.1:7676),因此它取決於您在開發AEM Edge函式中新增到AEM Edge函式的CORS標頭。 若沒有這些變數,瀏覽器會封鎖回應,而擷取呼叫會擲回一般網路錯誤。

呼叫AEM Edge函式

// blocks/estimated-delivery/estimated-delivery.js
async function fetchEstimatedDelivery(sku, postcode, signal) {
  const params = new URLSearchParams({ sku, postcode });
  const response = await fetch(`${getEstimatedDeliveryApiUrl()}?${params.toString()}`, {
    signal,
    cache: 'no-store',
  });

  const body = await response.json().catch(() => ({}));

  if (!response.ok) {
    const apiMessage = body.message || body.error;
    const err = new Error(apiMessage || 'Unable to check estimated delivery right now.');
    err.code = body.code;
    throw err;
  }

  return body;
}

err.code攜帶來自定義API合約 (MISSING_POSTCODEUNKNOWN_SKU)的相同code欄位,所以呼叫者可以在其上分支。 Edge Delivery Services區塊僅顯示messagecache: 'no-store'可防止瀏覽器快取個人化回應。 CDN自己的快取行為是由cdn.yaml中的skipCache單獨控制,涵蓋在建置API端點中。

連線提交處理常式

開發Edge Delivery Services區塊的表單標籤後,將此專案新增至decorate()。 這是核心模式:取消任何執行中的要求、顯示載入、呼叫函式,並將結果路由至setState

// blocks/estimated-delivery/estimated-delivery.js
form.addEventListener('submit', async (event) => {
  event.preventDefault();
  // ...extract and validate sku/postcode from the form, omitted here...

  activeRequest?.abort();
  const controller = new AbortController();
  activeRequest = controller;

  setState({ loading: true });

  try {
    const data = await fetchEstimatedDelivery(sku, postcode, controller.signal);
    setState({ data });
  } catch (err) {
    if (err.name === 'AbortError') return;
    setState({ error: formatError(err) });
  }
});

setState封裝renderResult(),可在載入、錯誤和成功標籤之間切換。 擲回的錯誤透過formatError()路由,可區分網路失敗(無法連線AEM Edge函式,因此本機開發伺服器未執行或尚未部署CDN路由)與AEM Edge函式有意傳回的業務錯誤,例如未知SKU。 完整處理常式也會在呼叫函式之前驗證郵遞區號使用者端,並在傳送請求時停用提交按鈕。 在estimated-delivery.js中檢視完整的接聽程式renderResult()formatError()

在本機測試完整回圈

在兩個開發伺服器都執行的情況下,開啟您在http://localhost:3000/dev/branches/estimated-delivery編寫的頁面,提交表單,然後確認結果會呈現為包含AEM Edge函式上游呼叫之資料的狀態彩色卡片。

以即時資料在本機轉譯的預估傳遞成功卡

然後確認其他兩種狀態:

  • 提交時郵遞區號欄位為空白。 Edge Delivery Services區塊應顯示「需要郵遞區號」而不進行網路呼叫,以確認在fetchEstimatedDelivery()之前執行使用者端檢查。

  • 停止aio aem edge-functions serve並重新提交。 Edge Delivery Services區塊應該顯示本機網路失敗提示,確認formatError()挑選了本機開發分支。

    停止本機Edge函式後 預估的傳遞網路失敗提示

開啟任一專案的瀏覽器主控台。 如果要求意外失敗,請先檢查是否為CORS錯誤(在AEM Edge函式中修正)或連線錯誤(AEM Edge函式的開發伺服器未執行)。

後續步驟

部署及驗證中,您部署兩個專案並確認相同的流程對您的開發網站有效,而不僅僅是本機。

其他資源

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