範例應用程式是探索Adobe Experience Manager(AEM)無頭功能的絕佳方式。 此React應用程式示範如何使用持續查詢,使用AEM GraphQL API來查詢內容。 適用於JavaScript的AEM無頭式用戶端可用來執行支援應用程式的GraphQL持續查詢。
檢視 GitHub原始碼
A 完整的逐步教學課程 說明此React應用程式的建置可用性。
應在本機安裝下列工具:
React應用程式可搭配下列AEM部署選項使用。 所有部署都需要 WKND Site v2.0.0+ 安裝。
React應用程式設計為連線至 AEM發佈 環境,但若React應用程式設定中提供驗證,則可從AEM Author取得內容。
複製 adobe/aem-guides-wknd-graphql
存放庫:
$ git clone git@github.com:adobe/aem-guides-wknd-graphql.git
編輯 aem-guides-wknd-graphql/react-app/.env.development
檔案和設定 REACT_APP_HOST_URI
指向您的target AEM。
如果連線至製作例項,請更新驗證方法。
# Server namespace
REACT_APP_HOST_URI=http://localhost:4503
#AUTH (Choose one method)
# Authentication methods: 'service-token', 'dev-token', 'basic' or leave blank to use no authentication
REACT_APP_AUTH_METHOD=basic
# For Bearer auth, use DEV token (dev-token) from Cloud console
REACT_APP_DEV_TOKEN=dev-token
# For Service toke auth, provide path to service token file (download file from Cloud console)
REACT_APP_SERVICE_TOKEN=auth/service-token.json
# For Basic auth, use AEM ['user','pass'] pair (eg for Local AEM Author instance)
REACT_APP_BASIC_AUTH_USER=admin
REACT_APP_BASIC_AUTH_PASS=admin
開啟終端機並執行命令:
$ cd aem-guides-wknd-graphql/react-app
$ npm install
$ npm start
新瀏覽器視窗應載入 http://localhost:3000
應用程式中應顯示來自WKND參考網站的歷險清單。
以下是如何建置React應用程式、如何連線至AEM Headless以使用GraphQL持續查詢擷取內容的摘要,以及如何呈現該資料的摘要。 您可以在上找到完整的程式碼 GitHub.
遵循AEM無頭式最佳實務,React應用程式使用AEM GraphQL持續存在的查詢來查詢冒險資料。 應用程式使用兩個持續的查詢:
wknd/adventures-all
持續查詢,會傳回AEM中具有一組縮略屬性的所有歷險。 這個持續的查詢會驅動初始檢視的探險清單。# Retrieves a list of all adventures
{
adventureList {
items {
_path
slug
title
price
tripLength
primaryImage {
... on ImageRef {
_path
mimeType
width
height
}
}
}
}
}
wknd/adventure-by-slug
持續查詢,其返回單個歷程,方法為 slug
(可唯一識別冒險的自訂屬性),包含完整的屬性集。 這個持續的查詢可支援探險詳細資訊的檢視。# Retrieves an adventure Content Fragment based on it's slug
# Example query variables:
# {"slug": "bali-surf-camp"}
# Technically returns an adventure list but since the the slug
# property is set to be unique in the CF Model, only a single CF is expected
query($slug: String!) {
adventureList(filter: {
slug: {
_expressions: [ { value: $slug } ]
}
}) {
items {
_path
title
slug
activity
adventureType
price
tripLength
groupSize
difficulty
price
primaryImage {
... on ImageRef {
_path
mimeType
width
height
}
}
description {
json
plaintext
}
itinerary {
json
plaintext
}
}
_references {
...on AdventureModel {
_path
slug
title
price
__typename
}
}
}
}
AEM持續查詢會透過HTTPGET執行,因此, AEM JavaScript適用的無頭式用戶端 用於 執行持續的GraphQL查詢 來抵御AEM,並將冒險內容載入應用程式中。
每個保存的查詢都有對應的React useEffect 鈎子 src/api/usePersistedQueries.js
,會非同步呼叫AEM HTTPGET持續存在的查詢端點,並傳回冒險資料。
每個函式依次調用 aemHeadlessClient.runPersistedQuery(...)
,執行持續的GraphQL查詢。
// src/api/usePersistedQueries.js
/**
* React custom hook that returns a list of adevntures by activity. If no activity is provided, all adventures are returned.
*
* Custom hook that calls the 'wknd-shared/adventures-all' or 'wknd-shared/adventures-by-activity' persisted query.
*
* @returns an array of Adventure JSON objects, and array of errors
*/
export function useAdventuresByActivity(adventureActivity) {
...
// If an activity is provided (i.e "Camping", "Hiking"...) call wknd-shared/adventures-by-activity query
if (adventureActivity) {
// The key is 'activity' as defined in the persisted query
const queryParameters = { activity: adventureActivity };
// Call the AEM GraphQL persisted query named "wknd-shared/adventures-by-activity" with parameters
response = await fetchPersistedQuery("wknd-shared/adventures-by-activity", queryParameters);
} else {
// Else call the AEM GraphQL persisted query named "wknd-shared/adventures-all" to get all adventures
response = await fetchPersistedQuery("wknd-shared/adventures-all");
}
...
}
...
/**
* Private function that invokes the AEM Headless client.
*
* @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 };
}
React應用程式使用兩種檢視來呈現網頁體驗中的冒險資料。
src/components/Adventures.js
調用 getAdventuresByActivity(..)
從 src/api/usePersistedQueries.js
並在清單中顯示傳回的歷險。
src/components/AdventureDetail.js
調用 getAdventureBySlug(..)
使用 slug
參數是透過 Adventures
元件,並顯示單一歷險的詳細資訊。
數個 環境變數 用於連線至AEM環境。 預設連線至執行中的AEM發佈 http://localhost:4503
. 更新 .env.development
檔案,若要變更AEM連線:
REACT_APP_HOST_URI=http://localhost:4502
:設為AEM目標主機REACT_APP_GRAPHQL_ENDPOINT=/content/graphql/global/endpoint.json
:設定GraphQL端點路徑。 此React應用程式不會使用此值,因為此應用程式僅使用持續的查詢。REACT_APP_AUTH_METHOD=
:慣用的驗證方法。 選用,依預設不使用驗證。
service-token
:使用服務憑證在AEM as a Cloud Service上取得存取權杖dev-token
:在AEMas a Cloud Service上使用開發代號進行本機開發basic
:透過本機AEM作者,將使用者/傳遞用於本機開發REACT_APP_AUTHORIZATION=admin:admin
:設定在連線至AEM製作環境時要使用的基本驗證憑證(僅限開發用)。 如果連線至發佈環境,則不需要此設定。REACT_APP_DEV_TOKEN
:開發代號字串。 若要連線至遠端執行個體,除了基本驗證(user:pass)之外,您還可以透過雲端主控台,搭配DEV Token使用承載驗證REACT_APP_SERVICE_TOKEN
:服務憑據檔案的路徑。 若要連線至遠端執行個體,您也可以使用服務代號(從開發人員控制台下載檔案)來完成驗證。使用Webpack開發伺服器時(npm start
)專案需仰賴 代理設定 使用 http-proxy-middleware
. 檔案的設定位置為 src/setupProxy.js 並需仰賴設定於的數個自訂環境變數 .env
和 .env.development
.
若連線至AEM製作環境,則對應的 驗證方法需要配置.
此React應用程式需仰賴在目標AEM環境上執行的AEM型CORS設定,並假設React應用程式執行於 http://localhost:3000
在開發模式中。 此 CORS設定 是 WKND站點.