AEM Headless SDK

AEM Headless SDK是一組程式庫,使用者端可使用這些程式庫,透過HTTP快速輕鬆地與AEM Headless API互動。

AEM Headless SDK適用於多種平台:

持續性 GraphQL 查詢

使用GraphQL透過持續查詢來查詢AEM (與 使用者端定義的GraphQL查詢)可讓開發人員在AEM中儲存查詢(但不儲存其結果),然後要求依名稱執行查詢。 持久查詢與SQL資料庫中預存程式的概念類似。

持續查詢的效能比使用者端定義的GraphQL查詢更高,因為持續查詢是使用HTTPGET執行,這在CDN和AEM Dispatcher層級中可以快取。 持久查詢也有效,定義API,並消除開發人員瞭解每個內容片段模式詳細資訊的需求。

程式碼範例 persisted-graphql-queries-code-examples

以下程式碼範例說明如何對AEM執行GraphQL持久查詢。

JavaScript範例

安裝 @adobe/aem-headless-client-js 藉由執行 npm install Node.js專案的根目錄中的命令。

code language-none
$ npm i @adobe/aem-headless-client-js

此程式碼範例說明如何使用查詢AEM @adobe/aem-headless-client-js npm模組使用 async/await 語法。 適用於JavaScript的AEM Headless SDK也支援 Promise語法.

此程式碼會假設使用名稱的持續查詢 wknd/adventureNames 已在AEM Author上建立並發佈至AEM Publish。

code language-javascript
import AEMHeadless from '@adobe/aem-headless-client-js';

// Initialize the AEMHeadless client with connection details
const aemHeadlessClient = new AEMHeadless({
    serviceURL: 'https://publish-p123-e789.adobeaemcloud.com',  // The AEM environment to query, this can be pulled out to env variables
    endpoint: '/content/cq:graphql/wknd-shared/endpoint.json',  // The AEM GraphQL endpoint, this is not used when invoking persisted queries.
})

/**
 * Uses the AEM Headless SDK to execute a persisted query with optional query variables.

 * @param {String} persistedQueryName the fully qualified name of the persisted query
 * @param {*} queryParameters an optional JavaScript object containing query parameters
 * @returns the GraphQL data or an error message
 */
export async function executePersistedQuery(persistedQueryName, queryParameters) {
    let data;
    let errors;

    try {
        // AEM GraphQL queries are asynchronous, either await their return or use Promise-based .then(..) { ... } syntax
        const response = await aemHeadlessClient.runPersistedQuery(persistedQueryName, queryParameters);
        // The GraphQL data is stored on the response's data field
        data = response.data;
    } catch (e) {
        console.error(e.toJSON())
        errors = e;
    }

    return { data, errors };
};

// Execute the persisted query using its name 'wknd-shared/adventures-by-slug' and optional query variables
let { data, errors } = executePersistedQuery('wknd-shared/adventures-by-slug', { "slug": "bali-surf-camp" });
React useEffect(..) 範例

安裝 @adobe/aem-headless-client-js 藉由執行 npm install React專案根目錄的命令。

code language-none
$ npm i @adobe/aem-headless-client-js

此程式碼範例說明如何使用 React useEffect(…) 勾點 以執行AEM GraphQL的非同步呼叫。

使用 useEffect 在React中進行非同步GraphQL呼叫很有用,因為:

  1. 它提供同步包裝函式,以供非同步呼叫AEM。
  2. 它減少了不必要的AEM請求。

此程式碼會假設使用名稱的持續查詢 wknd-shared/adventure-by-slug 已在AEM Author上建立並使用GraphiQL發佈至AEM Publish。

code language-javascript
import AEMHeadless from '@adobe/aem-headless-client-js';
import { useEffect, useState } from "react";

// Initialize the AEMHeadless client with connection details
const aemHeadlessClient = new AEMHeadless({
    serviceURL: 'https://publish-p123-e789.adobeaemcloud.com', // The AEM environment to query
    endpoint: '/content/cq:graphql/wknd-shared/endpoint.json'         // The AEM GraphQL endpoint, this is not used when invoking persisted queries.
})

/**
 * Private, shared function that invokes the AEM Headless client.
 * React components/views will invoke GraphQL via the custom React useEffect hooks defined below.
 *
 * @param {String} persistedQueryName the fully qualified name of the persisted query
 * @param {*} queryParameters an optional JavaScript object containing query parameters
 * @returns the GraphQL data or an error message
 */
async function fetchPersistedQuery(persistedQueryName, queryParameters) {
  let data;
  let err;

  try {
    // AEM GraphQL queries are asynchronous, either await their return or use Promise-based .then(..) { ... } syntax
    const response = await aemHeadlessClient.runPersistedQuery(
      persistedQueryName,
      queryParameters
    );
    // The GraphQL data is stored on the response's data field
    data = response?.data;
  } catch (e) {
    // An error occurred, return the error messages
    err = e
      .toJSON()
      ?.map((error) => error.message)
      ?.join(", ");
    console.error(e.toJSON());
  }

  return { data, err };
}

/**
 * Calls the 'wknd-shared/adventure-by-slug' and provided the {slug} as the persisted query's `slug` parameter.
 *
 * @param {String!} slug the unique slug used to specify the adventure to return
 * @returns a JSON object representing the adventure
 */
export function useAdventureBySlug(slug) {
  const [adventure, setAdventure] = useState(null);
  const [errors, setErrors] = useState(null);

  useEffect(() => {
    async function fetchData() {
      // The key is the variable name as defined in the persisted query, and may not match the model's field name
      const queryParameters = { slug: slug };

      // Invoke the persisted query, and pass in the queryParameters object as the 2nd parameter
      const { data, err } = await fetchPersistedQuery(
        "wknd-shared/adventure-by-slug",
        queryParameters
      );

      if (err) {
        // Capture errors from the HTTP request
        setErrors(err);
      } else if (data?.adventureList?.items?.length === 1) {
        // Set the adventure data after data validation (there should only be 1 matching adventure)
        setAdventure(data.adventureList.items[0]);
      } else {
        // Set an error if no adventure could be found
        setErrors(`Cannot find adventure with slug: ${slug}`);
      }
    }
    fetchData();
  }, [slug]);

  return { adventure, errors };
}

叫用自訂React useEffect 從React元件的其他位置連結。

code language-javascript
import useAdventureBySlug from '...';

let { data, errors } = useAdventureBySlug('bali-surf-camp');

新增 useEffect 可為React應用程式使用的每個持續查詢建立勾點。

GraphQL查詢

AEM支援使用者端定義的GraphQL查詢,不過使用AEM是最佳實務 持續的GraphQL查詢.

Webpack 5+

AEM Headless JS SDK有相依性 util Webpack 5+預設不包含。 如果您使用Webpack 5+,且收到下列錯誤:

Compiled with problems:
× ERROR in ./node_modules/@adobe/aio-lib-core-errors/src/AioCoreSDKErrorWrapper.js 12:13-28
Module not found: Error: Can't resolve 'util' in '/Users/me/Code/wknd-headless-examples/node_modules/@adobe/aio-lib-core-errors/src'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
    - add a fallback 'resolve.fallback: { "util": require.resolve("util/") }'
    - install 'util'
If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "util": false }

新增下列專案 devDependencies 至您的 package.json 檔案:

  "devDependencies": {
    "buffer": "npm:buffer@^6.0.3",
    "crypto": "npm:crypto-browserify@^3.12.0",
    "http": "npm:stream-http@^3.2.0",
    "https": "npm:https-browserify@^1.0.0",
    "stream": "npm:stream-browserify@^3.0.0",
    "util": "npm:util@^0.12.5",
    "zlib": "npm:browserify-zlib@^0.2.0"
  },

然後執行 npm install 以安裝相依性。

recommendation-more-help
e25b6834-e87f-4ff3-ba56-4cd16cdfdec4