Im vorherigen Kapitel haben Sie mit dem GraphiQL-Explorer persistierte Abfragen erstellt und aktualisiert.
Dieses Kapitel führt Sie durch die Schritte, die zur Integration der persistierten Abfragen in die WKND-Client-Anwendung (auch als WKND-App bezeichnet) mithilfe von HTTP-GET-Anfragen innerhalb vorhandener React-Komponenten erforderlich sind. Es umfasst außerdem eine optionale Herausforderung: Ihr erworbenes AEM Headless-Wissen und Programmier-Know-how zur Erweiterung der WKND-Client-Anwendung anzuwenden.
Dieses Dokument ist Teil eines mehrteiligen Tutorials. Bevor Sie mit diesem Kapitel fortfahren, vergewissern Sie sich, dass Sie die vorherigen Kapitel abgeschlossen haben. Die WKND-Client-Anwendung stellt eine Verbindung zum AEM-Veröffentlichungs-Service her. Daher ist es wichtig, dass Sie Folgendes im AEM-Veröffentlichungs-Service veröffentlicht haben.
Die IDE-Screenshots in diesem Kapitel stammen von Visual Studio Code.
Es ist ein Lösungspaket zur Installation verfügbar, das die Schritte in der AEM-Benutzeroberfläche für die Kapitel 1–4 abschließt. Dieses Paket ist nicht erforderlich, wenn die vorherigen Kapitel abgeschlossen wurden.
In diesem Tutorial erfahren Sie, wie Sie Anfragen für persistierte Abfragen mit dem AEM Headless-Client für JavaScript in die beispielhafte WKND GraphQL React-App integrieren.
Um während des Tutorials Zeit zu sparen, wird eine React-JS-App als Start bereitgestellt.
Klonen Sie das Repository adobe/aem-guides-wknd-graphql:
$ git clone git@github.com:adobe/aem-guides-wknd-graphql.git
Bearbeiten Sie die Datei aem-guides-wknd-graphql/advanced-tutorial/.env.development
und legen Sie REACT_APP_HOST_URI
so fest, dass auf den AEM Publish-Ziel-Service verwiesen wird.
Aktualisieren Sie die Authentifizierungsmethode, wenn Sie eine Verbindung zu einer Autoreninstanz herstellen.
# Server namespace
REACT_APP_HOST_URI=https://publish-pxx-eyy.adobeaemcloud.com
#AUTH (Choose one method)
# Authentication methods: 'service-token', 'dev-token', 'basic' or leave blank to use no authentication
REACT_APP_AUTH_METHOD=
# For Bearer auth, use DEV token (dev-token) from Cloud console
REACT_APP_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=
REACT_APP_BASIC_AUTH_PASS=
Die obigen Anweisungen sehen vor, die React-App mit dem AEM-Veröffentlichungs-Service zu verbinden. Um allerdings eine Verbindung zum AEM-Autoren-Service herzustellen, ist ein lokales Entwicklungs-Token für Ihre AEM as a Cloud Service-Zielumgebung erforderlich.
Es ist ebenfalls möglich, die App mit einer lokalen Autoreninstanz über das AEMaaCS-SDK mittels einfacher Authentifizierung zu verbinden.
Öffnen Sie ein Terminal und führen Sie die folgenden Befehle aus:
$ cd aem-guides-wknd-graphql/advanced-tutorial
$ npm install
$ npm start
Ein neues Browser-Fenster sollte unter http://localhost:3000 geladen werden.
Tippen Sie auf Camping > Yosemite Backpacking, um Details zum Yosemite Backpacking-Adventure anzuzeigen.
Öffnen Sie die Entwickler-Tools des Browsers und überprüfen Sie die XHR
-Anfrage
Es sollten GET
-Anfragen an den GraphQL-Endpunkt mit dem Konfigurationsnamen des Projekts (wknd-shared
), dem Namen der persistierten Abfrage (adventure-by-slug
), dem Variablennamen (slug
), dem Wert (yosemite-backpacking
) und den Sonderzeichen-Codierungen zu sehen sein.
Wenn Sie sich fragen, warum die GraphQL-API-Anfrage an http://localhost:3000
und NICHT an die Domain des AEM-Veröffentlichungs-Service gerichtet ist, finden Sie im grundlegenden Tutorial unter Unter der Haube weitere Informationen dazu.
Im Schritt zum Erstellen einer React-App mit Nutzung von AEM GraphQL-APIs des grundlegenden Tutorials hatten wir einige Schlüsseldateien überprüft und erweitert, um praktische Kenntnisse zu vermitteln. Bevor Sie die WKND-App verbessern, sehen Sie sich diese Schlüsseldateien an.
Adventures
Die Hauptansicht der WKND React-App entspricht der Liste aller Adventures. Sie können diese Adventures nach Aktivitätstyp filtern, z. B. Camping, Cycling. Diese Ansicht wird von der Adventures
-Komponente gerendert. Im Folgenden finden Sie die wichtigsten Implementierungsdetails:
src/components/Adventures.js
ruft den Hook useAllAdventures(adventureActivity)
auf, wobei hier das Argument adventureActivity
für den Aktivitätstyp steht.
Der Hook useAllAdventures(adventureActivity)
ist in der Datei src/api/usePersistedQueries.js
definiert. Basierend auf dem Wert von adventureActivity
wird bestimmt, welche persistierte Abfrage aufgerufen werden soll. Sofern der Wert nicht null ist, wird wknd-shared/adventures-by-activity
aufgerufen, andernfalls alle verfügbaren Adventures (wknd-shared/adventures-all
).
Der Hook verwendet als Hauptfunktion fetchPersistedQuery(..)
, die die Ausführung der Abfrage über aemHeadlessClient.js
an AEMHeadless
delegiert.
Der Hook gibt auch nur die relevanten Daten aus der AEM GraphQL-Antwort unter response.data?.adventureList?.items
zurück, sodass die React-Ansichtskomponente Adventures
unabhängig von den übergeordneten JSON-Strukturen sein kann.
Bei erfolgreicher Ausführung der Abfrage fügt die Render-Funktion AdventureListItem(..)
von Adventures.js
ein HTML-Element hinzu, um Bild-, Reisedauer-, Preis- und Titelinformationen anzuzeigen.
AdventureDetail
Die React-Komponente AdventureDetail
rendert die Details des Adventures. Im Folgenden finden Sie die wichtigsten Implementierungsdetails:
src/components/AdventureDetail.js
ruft den Hook useAdventureBySlug(slug)
auf, wobei hier das Argument slug
für den Abfrageparameter steht.
Wie oben ist der Hook useAdventureBySlug(slug)
in der Datei src/api/usePersistedQueries.js
definiert. Die persistierte Abfrage wknd-shared/adventure-by-slug
wird durch Delegieren über aemHeadlessClient.js
an AEMHeadless
aufgerufen.
Bei erfolgreicher Ausführung der Abfrage fügt die Render-Funktion AdventureDetailRender(..)
von AdventureDetail.js
ein HTML-Element hinzu, um Details zum Adventure anzuzeigen.
adventure-details-by-slug
Im vorherigen Kapitel haben wir die persistierte Abfrage adventure-details-by-slug
erstellt. Diese liefert zusätzliche Informationen zum Adventure, z. B. zum Ort, Lehrpersonal und Administrator-Team. Ersetzen Sie adventure-by-slug
durch die persistierte Abfrage adventure-details-by-slug
, um diese zusätzlichen Informationen zu rendern.
Öffnen Sie src/api/usePersistedQueries.js
.
Suchen Sie die Funktion useAdventureBySlug()
und aktualisieren Sie die Abfrage wie folgt:
...
// Call the AEM GraphQL persisted query named "wknd-shared/adventure-details-by-slug" with parameters
response = await fetchPersistedQuery(
"wknd-shared/adventure-details-by-slug",
queryParameters
);
...
Um weitere Adventure-Informationen anzuzeigen, öffnen Sie src/components/AdventureDetail.js
.
Suchen Sie die Funktion AdventureDetailRender(..)
und aktualisieren Sie die Rückgabefunktion wie folgt:
...
return (<>
<h1 className="adventure-detail-title">{title}</h1>
<div className="adventure-detail-info">
<LocationInfo {...location} />
...
<Location {...location} />
<Administrator {...administrator} />
<InstructorTeam {...instructorTeam} />
</div>
</>);
...
Definieren Sie auch die entsprechenden Render-Funktionen:
LocationInfo
function LocationInfo({name}) {
if (!name) {
return null;
}
return (
<>
<div className="adventure-detail-info-label">Location</div>
<div className="adventure-detail-info-description">{name}</div>
</>
);
}
Speicherort
function Location({ contactInfo }) {
if (!contactInfo) {
return null;
}
return (
<>
<div className='adventure-detail-location'>
<h2>Where we meet</h2>
<hr />
<div className="adventure-detail-addtional-info">Phone:{contactInfo.phone}</div>
<div className="adventure-detail-addtional-info">Email:{contactInfo.email}</div>
</div>
</>);
}
InstructorTeam
function InstructorTeam({ _metadata }) {
if (!_metadata) {
return null;
}
return (
<>
<div className='adventure-detail-team'>
<h2>Instruction Team</h2>
<hr />
<div className="adventure-detail-addtional-info">Team Name: {_metadata.stringMetadata[0].value}</div>
</div>
</>);
}
Administrator
function Administrator({ fullName, contactInfo }) {
if (!fullName || !contactInfo) {
return null;
}
return (
<>
<div className='adventure-detail-administrator'>
<h2>Administrator</h2>
<hr />
<div className="adventure-detail-addtional-info">Name: {fullName}</div>
<div className="adventure-detail-addtional-info">Phone: {contactInfo.phone}</div>
<div className="adventure-detail-addtional-info">Email: {contactInfo.email}</div>
</div>
</>);
}
Öffnen Sie src/components/AdventureDetail.scss
und fügen Sie die folgenden Klassendefinitionen hinzu:
.adventure-detail-administrator,
.adventure-detail-team,
.adventure-detail-location {
margin-top: 1em;
width: 100%;
float: right;
}
.adventure-detail-addtional-info {
padding: 10px 0px 5px 0px;
text-transform: uppercase;
}
Die aktualisierten Dateien finden Sie unter dem Projekt AEM Guides WKND – GraphQL (siehe Abschnitt Erweitertes Tutorial).
Nach Abschluss der oben genannten Verbesserungen sieht die WKND-App wie folgt aus und die Entwickler-Tools des Browsers zeigen den Aufruf der persisenten Abfrage adventure-details-by-slug
an.
Die Hauptansicht der WKND React-App ermöglicht es Ihnen, diese Adventures nach Aktivitätstyp wie Camping, Cycling zu filtern. Das WKND-Business-Team wünscht sich jedoch eine zusätzliche standortbasierte Filterfunktion. Die Anforderungen lauten:
Herzlichen Glückwunsch! Sie haben nun die Integration abgeschlossen und die persistierten Abfragen in die WKND-Beispielanwendung implementiert.