使用AEM的內容片段傳送OpenAPI建置React應用程式
在本章中,您將探索使用OpenAPI傳送AEM內容片段如何推動外部應用程式中的體驗。
一個簡單的React應用程式可用來請求和顯示透過OpenAPI的AEM內容片段傳遞公開的 團隊 和 人員 內容。 React的使用基本上不重要,只要可以向AEM as a Cloud Service發出HTTP請求,消費的外部應用程式便可以在任何平台的任何框架中撰寫。
先決條件
假設已完成此多部分教學課程前幾部分所概述的步驟。
必須安裝下列軟體:
目標
瞭解如何:
- 下載並啟動範例React應用程式。
- 使用OpenAPI叫用AEM內容片段傳送,以取得團隊及其參考成員的清單。
- 使用OpenAPI叫用AEM內容片段傳送,以擷取團隊成員的詳細資訊。
在AEM as a Cloud Service上設定CORS
此範例React應用程式會在本機(在http://localhost:3000)執行,並使用OpenAPI API連線至AEM Publish服務的AEM內容片段傳送。 若要允許此連線,必須在AEM Publish (或Preview)服務上設定CORS (跨原始資源共用)。
依照設定在上執行的SPA的http://localhost:3000指示,允許CORS要求傳送至AEM Publish服務。
本機CORS Proxy
或者,若要進行開發,請執行本機CORS Proxy,以提供AEM的CORS友好連線。
$ npm install --global lcp
$ lcp --proxyUrl https://publish-p<PROGRAM_ID>-e<ENVIRONMENT_ID>.adobeaemcloud.com
將--proxyUrl值更新至您的AEM發佈(或預覽) URL。
在本機CORS Proxy執行下,存取位於http://localhost:8010/proxy的AEM內容片段傳送API以避免CORS問題。
複製範例React應用程式
實作一個現成的範例React應用程式,其中包含與OpenAPI的AEM內容片段傳送互動所需的程式碼,並顯示從這些API取得的團隊和人員資料。
範例React應用程式原始碼為可在Github.com上取得。
若要取得React應用程式:
-
從Github.com從
headless_open-api_basic標籤複製範例WKND OpenAPI React應用程式。code language-shell $ cd ~/Code $ git clone git@github.com:adobe/aem-tutorials.git $ cd aem-tutorials $ git fetch --tags $ git tag $ git checkout tags/headless_open-api_basic -
導覽至
headless/open-api/basic資料夾,並在IDE中開啟。code language-shell $ cd ~/Code/aem-tutorials/headless/open-api/basic $ code . -
更新
.env以連線至AEM as a Cloud Service Publish服務,因為這是發佈內容片段的位置。 如果您想要使用AEM預覽服務測試應用程式(且內容片段會發佈在那裡),這可以指向AEM預覽服務。code language-none # AEM Publish (or Preview) service that provides Content Fragments REACT_APP_HOST_URI=https://publish-p123-e456.adobeaemcloud.com使用本機CORS Proxy時,將
REACT_APP_HOST_URI設為http://localhost:8010/proxy。code language-none # AEM Publish (or Preview) service that provides Content Fragments REACT_APP_HOST_URI=http://localhost:8010/proxy -
啟動React應用程式
code language-shell $ cd ~/Code/aem-tutorials/headless/open-api/basic $ npm install $ npm start -
React應用程式會在http://localhost:3000/上以開發模式啟動。 在教學課程中對React應用程式所做的變更,會立即反映在網頁瀏覽器中。
> // TODO:依照AEM Headless教學課程中的步驟實作此專案
> // *****************************
React應用程式剖析
範例React應用程式有三個主要部分需要更新。
.env檔案包含AEM發佈(或預覽)服務URL。src/components/Teams.js會顯示團隊及其成員的清單。src/components/Person.js會顯示單一團隊成員的詳細資料。
實作團隊功能
建置在React應用程式主要檢視上顯示團隊及其成員的功能。 此功能需要:
- 新的自訂React useEffect勾點會透過擷取要求叫用 列出所有內容片段API,然後取得每個
fullName的teamMember值以供顯示。
完成後,應用程式的主要檢視會填入AEM中的團隊資料。
-
開啟
src/components/Teams.js。 -
實作 Teams 元件以從List all Content Fragments API擷取Teams清單,並轉譯Teams內容。 此程式分為下列步驟:
-
建立叫用AEM的
useEffect列出所有內容片段 API並將資料儲存到React元件狀態的 連結。 -
針對傳回的每個 團隊 內容片段,叫用 取得內容片段 API以擷取團隊的完整水合詳細資訊,包括其成員及其
fullNames。 -
使用
Team函式轉譯Teams資料。code language-javascript import { useEffect, useState } from "react"; import { Link } from "react-router-dom"; import "./Teams.scss"; function Teams() { // The teams folder is the only folder-tree that is allowed to contain Team Content Fragments. const TEAMS_FOLDER = '/content/dam/my-project/en/teams'; // State to store the teams data const [teams, setTeams] = useState(null); useEffect(() => { /** * Fetches all teams and their associated member details * This is a two-step process: * 1. First, get all team content fragments from the specified folder * 2. Then, for each team, fetch the full details including hydrated references to get the team member names */ const fetchData = async () => { try { // Step 1: Fetch all teams from the teams folder const response = await fetch( `${process.env.REACT_APP_HOST_URI}/adobe/contentFragments?path=${TEAMS_FOLDER}` ); const allTeams = (await response.json()).items || []; // Step 2: Fetch detailed information for each team with hydrated references const hydratedTeams = []; for (const team of allTeams) { const hydratedTeamResponse = await fetch( `${process.env.REACT_APP_HOST_URI}/adobe/contentFragments/${team.id}?references=direct-hydrated` ); hydratedTeams.push(await hydratedTeamResponse.json()); } setTeams(hydratedTeams); } catch (error) { console.error("Error fetching content fragments:", error); } }; fetchData(); }, [TEAMS_FOLDER]); // Show loading state while teams data is being fetched if (!teams) { return <div>Loading teams...</div>; } // Render the teams return ( <div className="teams"> {teams.map((team, index) => { return ( <Team key={index} {..team} /> ); })} </div> ); } /** * Team component - renders a single team with its details and members * @param {string} fields - The authorable fields * @param {Object} references - Hydrated references containing member details such as fullName */ function Team({ fields, references, path }) { if (!fields.title || !fields.teamMembers) { return null; } return ( <div className="team"> <h2 className="team__title">{fields.title}</h2> {/* Render description as HTML using dangerouslySetInnerHTML */} <p className="team__description" dangerouslySetInnerHTML={{ __html: fields.description.value }} /> <div> <h4 className="team__members-title">Members</h4> <ul className="team__members"> {/* Render each team member as a link to their detail page */} {fields.teamMembers.map((teamMember, index) => { return ( <li key={index} className="team__member"> <Link to={`/person/${teamMember}`}> {/* Display the full name from the hydrated reference */} {references[teamMember].value.fields.fullName} </Link> </li> ); })} </ul> </div> </div> ); } export default Teams;
實作人員功能
完成團隊功能後,請實作該功能以處理團隊成員或個人詳細資訊上的顯示。
若要這麼做:
-
開啟
src/components/Person.js -
在
PersonReact元件中,剖析id路由引數。 請注意,React應用程式的路由先前已設定為接受idURL引數(請參閱/src/App.js)。 -
從AEM擷取人員資料取得內容片段API。
code language-javascript import "./Person.scss"; import { useEffect, useState } from "react"; import { useParams } from "react-router-dom"; /** * Person component - displays detailed information about a single person * Fetches person data from AEM using the ID from the URL parameters */ function Person() { // Get the person ID from the URL parameter const { id } = useParams(); // State to store the person data const [person, setPerson] = useState(null); useEffect(() => { /** * Fetches person data from AEM Content Fragment Delivery API * Uses the ID from URL parameters to get the specific person's details */ const fetchData = async () => { try { /* Hydrate references for access to profilePicture asset path */ const response = await fetch( `${process.env.REACT_APP_HOST_URI}/adobe/contentFragments/${id}?references=direct-hydrated` ); const json = await response.json(); setPerson(json || null); } catch (error) { console.error("Error fetching person data:", error); } }; fetchData(); }, [id]); // Re-fetch when ID changes // Show loading state while person data is being fetched if (!person) { return <div>Loading person...</div>; } return ( <div className="person"> {/* Person profile image - Look up the profilePicture reference in the references object */} <img className="person__image" src={process.env.REACT_APP_HOST_URI + person.references[person.fields.profilePicture].value.path} alt={person.fields.fullName} /> {/* Display person's occupations */} <div className="person__occupations"> {person.fields.occupation.map((occupation, index) => { return ( <span key={index} className="person__occupation"> {occupation} </span> ); })} </div> {/* Person's main content: name and biography */} <div className="person__content"> <h1 className="person__full-name">{person.fields.fullName}</h1> {/* Render biography as HTML content */} <div className="person__biography" dangerouslySetInnerHTML={{ __html: person.fields.biographyText.value }} /> </div> </div> ); } export default Person;
取得完成的程式碼
本章的完整原始碼為,可在Github.com上取得。
$ git fetch --tags
$ git tag
$ git checkout tags/headless_open-api_basic_4-end
試用應用程式
檢閱應用程式http://localhost:3000/並按一下 團隊成員 連結。 您也可以新增更多團隊和/或成員至Alpha團隊,方法是在AEM Author服務中新增內容片段並加以發佈。
內部運作原理
當您與React應用程式互動時,開啟瀏覽器的 開發人員工具>網路 主控台和 篩選 以擷取/adobe/contentFragments請求。
恭喜!
恭喜!您已成功建立React應用程式,以便透過OpenAPI使用及顯示AEM內容片段傳送的內容片段。