Beispielanwendungen eignen sich hervorragend, um die Headless-Funktionen von Adobe Experience Manager (AEM) zu erkunden. Diese React-App zeigt, wie Sie mithilfe von AEM GraphQL-APIs unter Verwendung von persistierten Abfragen Inhalte abfragen können. Der AEM Headless-Client für JavaScript wird verwendet, um die von GraphQL gespeicherten Abfragen auszuführen, die die App antreiben.
Sie finden den Quell-Code auf GitHub.
Es ist ein vollständiges Schritt-für-Schritt-Tutorial verfügbar, in dem beschrieben wird, wie diese React-App erstellt wurde.
Folgende Tools sollten lokal installiert werden:
Die React-App funktioniert mit den folgenden AEM-Bereitstellungsoptionen. Für alle Implementierungen muss die WKND-Site v2.0.0+ installiert sein.
Die React-App ist für die Verbindung mit einer AEM Publish-Umgebung vorgesehen, kann jedoch Inhalte von AEM Author beziehen, wenn die Authentifizierung in der Konfiguration der React-App bereitgestellt wird.
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/react-app/.env.development
und richten Sie den REACT_APP_HOST_URI
so ein, dass er auf Ihre AEM verweist.
Aktualisieren Sie die Authentifizierungsmethode, wenn Sie eine Verbindung zu einer Autoreninstanz herstellen.
# 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
Öffnen Sie ein Terminal und führen Sie die folgenden Befehle aus:
$ cd aem-guides-wknd-graphql/react-app
$ npm install
$ npm start
Ein neues Browser-Fenster sollte in http://localhost:3000 geladen werden.
Eine Liste der Adventures von der WKND-Referenz-Website sollte auf der App angezeigt werden.
Nachstehend finden Sie eine Zusammenfassung dazu, wie die React-App aufgebaut ist, wie sie eine Verbindung zu AEM Headless herstellt, um mithilfe von persistierten Abfragen von GraphQL Inhalte abzurufen, und wie diese Daten dargestellt werden. Den vollständigen Code finden Sie auf GitHub.
Gemäß den Best Practices für AEM verwendet die React-App persistierte Anfragen von AEM GraphQL, um Adventure-Daten abzufragen. Die Anwendung verwendet zwei persistierte Abfragen:
wknd/adventures-all
gibt alle Adventures in AEM mit einer gekürzten Reihe von Eigenschaften zurück. Diese persistierte Abfrage bestimmt die Erlebnisliste der ersten Ansicht.# Retrieves a list of all adventures
{
adventureList {
items {
_path
slug
title
price
tripLength
primaryImage {
... on ImageRef {
_path
mimeType
width
height
}
}
}
}
}
wknd/adventure-by-slug
gibt ein einzelnes Adventure durch slug
(eine benutzerdefinierte Eigenschaft, die ein Adventure eindeutig identifiziert) mit einer vollständigen Reihe von Eigenschaften zurück. Diese persistierte Abfrage ermöglicht Detailansichten des Adventures.# 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
}
}
}
}
Die persistierten Abfragen von AEM werden über HTTP-GET ausgeführt, und daher wird der AEM Headless-Client für JavaScript verwendet, um die persistierten GraphQL-Abfragen an AEM auszuführen und den Adventure-Inhalt in die App zu laden.
Jede persistierte Abfrage hat einen entsprechenden React-useEffect-Hook in src/api/usePersistedQueries.js
, der asynchron den Endpunkt der asynchronen Abfrage von AEM HTTP-GET abruft und die Adventure-Daten zurückgibt.
Jede Funktion ruft wiederum aemHeadlessClient.runPersistedQuery(...)
auf, um die persistierte GraphQL-Abfrage auszuführen.
// 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 };
}
Die React-App verwendet zwei Ansichten, um die Adventure-Daten im Web-Erlebnis darzustellen.
src/components/Adventures.js
Ruft getAdventuresByActivity(..)
von src/api/usePersistedQueries.js
auf und zeigt die zurückgegebenen Adventures in einer Liste an.
src/components/AdventureDetail.js
Ruft getAdventureBySlug(..)
mithilfe des Parameters slug
über die Adventure-Auswahl auf der Adventures
-Komponente auf und zeigt die Details eines einzelnen Adventures an.
Mehrere Umgebungsvariablen werden verwendet, um eine Verbindung zu einer AEM-Umgebung herzustellen. Standardmäßige Verbindungen zu AEM Publish, das unter http://localhost:4503
ausgeführt wird. Aktualisieren Sie die Datei .env.development
, um die AEM-Verbindung zu ändern:
REACT_APP_HOST_URI=http://localhost:4502
: Auf AEM-Ziel-Host einstellenREACT_APP_GRAPHQL_ENDPOINT=/content/graphql/global/endpoint.json
: Den GraphQL-Endpunktpfad festlegen. Dies wird von dieser React-App nicht verwendet, da diese App nur persistierte Abfragen verwendet.REACT_APP_AUTH_METHOD=
: Die bevorzugte Authentifizierungsmethode. Optional, da standardmäßig keine Authentifizierung verwendet wird.
service-token
: Verwenden von Service-Anmeldeinformationen, um ein Zugriffstoken für AEM as a Cloud Service zu erhalten.dev-token
: Verwenden des Entwicklungs-Tokens für die lokale Entwicklung auf AEM as a Cloud Servicebasic
: Verwenden von Benutzernamen/Kennwort für lokale Entwicklung mit lokaler AEM-AutoreninstanzREACT_APP_AUTHORIZATION=admin:admin
: Festlegen der grundlegenden Authentifizierungs-Anmeldeinformationen, die beim Herstellen einer Verbindung zu einer AEM Author-Umgebung verwendet werden (nur für die Entwicklung). Wenn Sie eine Verbindung zu einer Veröffentlichungsumgebung herstellen, ist diese Einstellung nicht erforderlich.REACT_APP_DEV_TOKEN
: Entwicklungs-Token-Zeichenfolge. Um eine Verbindung zu einer Remote-Instanz herzustellen, können Sie neben der einfachen Authentifizierung (user:pass) auch die Bearer-Authentifizierung mit dem Entwicklungs-Token über die Cloud-Konsole verwendenREACT_APP_SERVICE_TOKEN
: Pfad zur Datei mit den Service-Anmeldeinformationen. Um eine Verbindung zu einer Remote-Instanz herzustellen, kann die Authentifizierung auch über das Service-Token erfolgen (laden Sie die Datei über die Developer Console herunter).Bei Verwendung des Webpack Development Servers (npm start
) verlässt sich das Projekt auf eine Proxy-Einrichtung unter Verwendung von http-proxy-middleware
. Die Datei wird konfiguriert unter src/setupProxy.js und verwendet mehrere benutzerdefinierte Umgebungsvariablen, die in .env
und .env.development
festgelegt werden.
Wenn eine Verbindung zu einer AEM Author-Umgebung hergestellt wird, muss die entsprechende Authentifizierungsmethode konfiguriert werden.
Diese React-App basiert auf einer AEM-basierten CORS-Konfiguration, die in der AEM-Zielumgebung ausgeführt wird, und geht davon aus, dass die React-App auf http://localhost:3000
im Entwicklungsmodus ausgeführt wird. Die CORS-Konfiguration ist Teil der WKND-Site.