Créer une application React avec les OpenAPI de diffusion de fragments de contenu d’AEM
Dans ce chapitre, vous découvrez comment la diffusion de fragments de contenu AEM avec les API OpenAPI peut améliorer l’expérience sur les applications externes.
Une application React simple est utilisée pour interroger et afficher du contenu Équipe et Personne exposé par la diffusion de fragments de contenu AEM avec les API OpenAPI. L’utilisation de React n’est pas vraiment importante, et l’application externe consommatrice peut être écrite dans n’importe quel cadre pour n’importe quelle plateforme tant qu’elle est en mesure d’envoyer des requêtes HTTP à AEM as a Cloud Service.
Conditions préalables
Nous partons du principe que les étapes décrites dans les parties précédentes de ce tutoriel en plusieurs parties ont été terminées.
Les logiciels suivants doivent être installés :
Objectifs
Découvrez comment :
- Télécharger et démarrer l’exemple d’application React.
- Appeler la diffusion de fragments de contenu AEM avec les API OpenAPI pour obtenir la liste des équipes et de leurs membres référencés.
- Appeler la diffusion de fragments de contenu AEM avec les API OpenAPI pour récupérer les détails d’un membre de l’équipe.
Configurer CORS sur AEM as a Cloud Service.
Cet exemple d’application React s’exécute localement (sur http://localhost:3000
) et se connecte à la diffusion de fragments de contenu AEM du service de publication AEM avec les API OpenAPI. Pour autoriser cette connexion, CORS (partage des ressources entre origines multiples) doit être configuré sur le service de publication (ou de prévisualisation) AEM.
Proxy CORS local
Pour le développement, vous pouvez également exécuter un proxy CORS local qui établit une connexion CORS à AEM.
$ npm install --global lcp
$ lcp --proxyUrl https://publish-p<PROGRAM_ID>-e<ENVIRONMENT_ID>.adobeaemcloud.com
Mettez à jour la valeur --proxyUrl
avec l’URL de votre instance de publication (ou de prévisualisation) AEM.
Une fois le proxy CORS local en cours d’exécution, accédez aux API de diffusion de fragments de contenu AEM sur http://localhost:8010/proxy
pour éviter les problèmes liés à CORS.
Cloner l’exemple d’application React
Un exemple d’application React dérivée est implémenté avec le code requis pour interagir avec la diffusion de fragments de contenu AEM avec les API OpenAPI et afficher les données de l’équipe et de la personne provenant de celles-ci.
Le code source de l’exemple d’application React est disponible sur Github.com.
Pour obtenir l’application React :
-
Clonez l’exemple d’application React OpenAPI WKND de Github.com à partir de la balise
headless_open-api_basic
.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
-
Accédez au dossier
headless/open-api/basic
et ouvrez-le dans votre IDE.code language-shell $ cd ~/Code/aem-tutorials/headless/open-api/basic $ code .
-
Mettez à jour
.env
pour vous connecter au service de publication AEM as a Cloud Service, car c’est là que nos fragments de contenu sont publiés. Il peut s’agir du service de prévisualisation AEM si vous souhaitez tester l’application avec le service de prévisualisation AEM (et que les fragments de contenu y sont publiés).code language-none # AEM Publish (or Preview) service that provides Content Fragments REACT_APP_HOST_URI=https://publish-p123-e456.adobeaemcloud.com
Lors de l’utilisation de Proxy CORS local, définissez
REACT_APP_HOST_URI
surhttp://localhost:8010/proxy
.code language-none # AEM Publish (or Preview) service that provides Content Fragments REACT_APP_HOST_URI=http://localhost:8010/proxy
-
Démarrer l’application React
code language-shell $ cd ~/Code/aem-tutorials/headless/open-api/basic $ npm install $ npm start
-
L’application React démarre en mode de développement sur http://localhost:3000/. Les modifications apportées à l’application React tout au long du tutoriel sont répercutées immédiatement dans le navigateur web.
// Tâche : implémentez ceci en suivant les étapes du tutoriel sur AEM Headless.
//*********************************
Anatomie de l’application React
L’exemple d’application React comporte trois parties principales qui requièrent une mise à jour.
- Le fichier
.env
contient l’URL du service de publication (ou de prévisualisation) AEM. - Le fichier
src/components/Teams.js
affiche une liste des équipes et de leurs membres. - Le fichier
src/components/Person.js
affiche les détails d’un seul membre de l’équipe.
Implémenter la fonctionnalité Équipes
Développez la fonctionnalité pour afficher les équipes et leurs membres sur la vue principale de l’application React. Cette fonctionnalité requiert :
- Un nouveau crochet useEffect React personnalisé qui appelle l’API Répertorier tous les fragments de contenu via une requête de récupération, puis obtient la valeur
fullName
de chaqueteamMember
à afficher.
Une fois l’opération terminée, la vue principale de l’application est renseignée avec les données de l’équipe provenant d’AEM.
-
Ouvrez
src/components/Teams.js
. -
Implémentez le composant Équipes pour récupérer la liste des équipes à partir de l’API Répertorier tous les fragments de contenu et générer le rendu du contenu des équipes. Cela implique les étapes suivantes :
-
Créez un crochet
useEffect
qui appelle l’API Répertorier tous les fragments de contenu d’AEM et stocke les données dans l’état du composant React. -
Pour chaque fragment de contenu Équipe renvoyé, appelez l’API Obtenir un fragment de contenu pour récupérer les détails d’hydratation complets de l’équipe, y compris ses membres et leurs
fullNames
. -
Générez le rendu des données d’équipes à l’aide de la fonction
Team
.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;
Implémenter la fonctionnalité Personne
Une fois la fonctionnalité Équipes terminée, implémentez la fonctionnalité permettant de gérer l’affichage des détails d’un ou d’une membre de l’équipe, ou d’une personne.
Pour ce faire :
-
Ouvrez
src/components/Person.js
. -
Dans le composant React
Person
, analysez le paramètre d’itinéraireid
. Notez que les itinéraires de l’application React ont été précédemment configurés pour accepter le paramètre d’URLid
(voir/src/App.js
). -
Récupérez les données de personne d’AEM à l’aide de l’API Obtenir un fragment de contenu.
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;
Obtenir le code terminé
Le code source complet de ce chapitre est disponible sur Github.com.
$ git fetch --tags
$ git tag
$ git checkout tags/headless_open-api_basic_4-end
Essayer l’application
Vérifiez l’application http://localhost:3000/ et cliquez sur les liens Membre de l’équipe. Vous pouvez également ajouter d’autres équipes et/ou membres à l’équipe Alpha en ajoutant des fragments de contenu dans le service de création AEM et en les publiant.
Ce qui se passe.
Ouvrez la console Outils de développement > Réseau du navigateur et filtrez les requêtes de récupération de /adobe/contentFragments
lorsque vous interagissez avec l’application React.
Félicitations !
Félicitations ! Vous avez créé une application React pour consommer et afficher des fragments de contenu à partir de la diffusion de fragments de contenu AEM avec les API OpenAPI.