App React react-app
[AEM headless as a Cloud Service]{class="badge informative"}
Le applicazioni di esempio sono un ottimo modo per esplorare le funzionalità headless di Adobe Experience Manager (AEM). Questa applicazione React illustra come eseguire query sui contenuti che utilizzano le API GraphQL dell’AEM utilizzando query persistenti. Il client headless AEM per JavaScript viene utilizzato per eseguire le query persistenti GraphQL che alimentano l’app.
Visualizza il codice sorgente in GitHub
È disponibile un tutorial completo che descrive come è stata generata l'app React.
Prerequisiti prerequisites
I seguenti strumenti devono essere installati localmente:
Requisiti AEM
L’applicazione React funziona con le seguenti opzioni di implementazione dell’AEM. Tutte le distribuzioni richiedono l'installazione del sito WKND v3.0.0+.
- AEM as a Cloud Service
- Configurazione locale con SDK AEM Cloud Service
- Richiede [JDK 11](https://experience.adobe.com/#/downloads/content/software-distribution/en/general.html?1_group.propertyvalues.property=.%2Fjcr%3Acontent%2Fmetadata%2Fdc%3AsoftwareType&1_group.propertyvalues.operation=equals&1_group.propertyvalues.0_values=tipo di software%3Atooling&fulltext=Oracle%7E+JDK%7E+11%7E&orderby=%40jcr%3Acontent%2Fjcr%3AlastModified&orderby.sort=desc&layout=list&p.offset=0&p.limit=14)
L'applicazione React è progettata per connettersi a un ambiente AEM Publish, tuttavia può creare contenuto da AEM Author se l'autenticazione viene fornita nella configurazione dell'applicazione React.
Come usare
-
Clona l'archivio
adobe/aem-guides-wknd-graphql
:code language-shell $ git clone git@github.com:adobe/aem-guides-wknd-graphql.git
-
Modificare il file
aem-guides-wknd-graphql/react-app/.env.development
e impostareREACT_APP_HOST_URI
in modo che punti all'AEM di destinazione.Se ti connetti a un’istanza Autore, aggiorna il metodo di autenticazione.
code language-plain # Server namespace REACT_APP_HOST_URI=https://publish-p123-e456.adobeaemcloud.com #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
-
Apri un terminale ed esegui i comandi:
code language-shell $ cd aem-guides-wknd-graphql/react-app $ npm install $ npm start
-
Una nuova finestra del browser deve essere caricata su http://localhost:3000
-
Nell’applicazione deve essere visualizzato un elenco di avventure dal sito di riferimento WKND.
Il codice
Di seguito è riportato un riepilogo di come viene creata l’applicazione React, di come si connette a AEM Headless per recuperare contenuti utilizzando query persistenti di GraphQL e di come vengono presentati tali dati. Il codice completo si trova su GitHub.
Query persistenti
Seguendo le best practice di AEM Headless, l’applicazione React utilizza query persistenti di AEM GraphQL per eseguire query sui dati di avventura. L’applicazione utilizza due query persistenti:
- Query persistente
wknd/adventures-all
, che restituisce tutte le avventure in AEM con un set abbreviato di proprietà. Questa query persistente guida l’elenco di avventure della visualizzazione iniziale.
# Retrieves a list of all Adventures
#
# Optional query variables:
# - { "offset": 10 }
# - { "limit": 5 }
# - {
# "imageFormat": "JPG",
# "imageWidth": 1600,
# "imageQuality": 90
# }
query ($offset: Int, $limit: Int, $sort: String, $imageFormat: AssetTransformFormat=JPG, $imageWidth: Int=1200, $imageQuality: Int=80) {
adventureList(
offset: $offset
limit: $limit
sort: $sort
_assetTransform: {
format: $imageFormat
width: $imageWidth
quality: $imageQuality
preferWebp: true
}) {
items {
_path
slug
title
activity
price
tripLength
primaryImage {
... on ImageRef {
_path
_dynamicUrl
}
}
}
}
}
- Query persistente
wknd/adventure-by-slug
, che restituisce una singola avventura dislug
(una proprietà personalizzata che identifica in modo univoco un'avventura) con un set completo di proprietà. Questa query persistente attiva le visualizzazioni dei dettagli dell’avventura.
# Retrieves an Adventure Fragment based on it's unique slug.
#
# Required query variables:
# - {"slug": "bali-surf-camp"}
#
# Optional query variables:
# - {
# "imageFormat": "JPG",
# "imageSeoName": "my-adventure",
# "imageWidth": 1600,
# "imageQuality": 90
# }
#
# This query returns an adventure list but since the the slug property is set to be unique in the Content Fragment Model, only a single Content Fragment is expected.
query ($slug: String!, $imageFormat:AssetTransformFormat=JPG, $imageSeoName: String, $imageWidth: Int=1200, $imageQuality: Int=80) {
adventureList(
filter: {slug: {_expressions: [{value: $slug}]}}
_assetTransform: {
format: $imageFormat
seoName: $imageSeoName
width: $imageWidth
quality: $imageQuality
preferWebp: true
}) {
items {
_path
title
slug
activity
adventureType
price
tripLength
groupSize
difficulty
price
primaryImage {
... on ImageRef {
_path
_dynamicUrl
}
}
description {
json
plaintext
html
}
itinerary {
json
plaintext
html
}
}
_references {
... on AdventureModel {
_path
slug
title
price
__typename
}
}
}
}
Esegui query persistente GraphQL
Le query persistenti dell'AEM vengono eseguite su HTTP GET, pertanto il client AEM Headless per JavaScript viene utilizzato per eseguire le query GraphQL persistenti sull'AEM e caricare il contenuto dell'avventura nell'app.
Ogni query persistente ha un hook React useEffect corrispondente in src/api/usePersistedQueries.js
, che chiama in modo asincrono l'endpoint della query persistente HTTP AEM GET e restituisce i dati relativi all'avventura.
Ogni funzione a sua volta richiama aemHeadlessClient.runPersistedQuery(...)
, eseguendo la query GraphQL persistente.
// 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, params = {}) {
...
let queryVariables = params;
// 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
queryVariables = { ...queryVariables, activity: adventureActivity };
// Call the AEM GraphQL persisted query named "wknd-shared/adventures-by-activity" with parameters
response = await fetchPersistedQuery("wknd-shared/adventures-by-activity", queryVariables);
} else {
// Else call the AEM GraphQL persisted query named "wknd-shared/adventures-all" to get all adventures
response = await fetchPersistedQuery("wknd-shared/adventures-all", queryVariables);
}
...
}
...
/**
* 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 };
}
Viste
L’applicazione React utilizza due visualizzazioni per presentare i dati dell’avventura nell’esperienza web.
-
src/components/Adventures.js
Richiama
getAdventuresByActivity(..)
dasrc/api/usePersistedQueries.js
e visualizza le avventure restituite in un elenco. -
src/components/AdventureDetail.js
Richiama
getAdventureBySlug(..)
utilizzando il parametroslug
trasmesso tramite la selezione di avventura nel componenteAdventures
e visualizza i dettagli di una singola avventura.
Variabili di ambiente
Diverse variabili di ambiente sono utilizzate per connettersi a un ambiente AEM. L'impostazione predefinita si connette al Publish AEM in esecuzione alle http://localhost:4503
. Aggiornare il file .env.development
per modificare la connessione AEM:
-
REACT_APP_HOST_URI=https://publish-p123-e456.adobeaemcloud.com
: impostato sull'host di destinazione AEM -
REACT_APP_GRAPHQL_ENDPOINT=/content/graphql/global/endpoint.json
: impostare il percorso dell'endpoint GraphQL. Questa app React non la utilizza, in quanto utilizza solo query persistenti. -
REACT_APP_AUTH_METHOD=
: metodo di autenticazione preferito. Facoltativo, per impostazione predefinita non viene utilizzata alcuna autenticazione.service-token
: usa le credenziali del servizio per ottenere un token di accesso su AEM as a Cloud Servicedev-token
: usa il token di sviluppo per lo sviluppo locale su AEM as a Cloud Servicebasic
: usa user/pass per lo sviluppo locale con Autore AEM locale- Lascia vuoto per connetterti a AEM senza autenticazione
-
REACT_APP_AUTHORIZATION=admin:admin
: impostare le credenziali di autenticazione di base da utilizzare per la connessione a un ambiente di creazione AEM (solo per lo sviluppo). Se ci si connette a un ambiente Publish, questa impostazione non è necessaria. -
REACT_APP_DEV_TOKEN
: stringa token di sviluppo. Per connettersi all’istanza remota, oltre all’autenticazione di base (utente:passaggio) puoi utilizzare l’autenticazione Bearer con il token DEV dalla console Cloud -
REACT_APP_SERVICE_TOKEN
: percorso del file delle credenziali del servizio. Per connettersi all’istanza remota, l’autenticazione può essere eseguita anche con il token di servizio (scarica il file da Developer Console).
Richieste proxy AEM
Quando si utilizza il server di sviluppo Webpack (npm start
), il progetto si basa su una configurazione proxy che utilizza http-proxy-middleware
. Il file è configurato in src/setupProxy.js e si basa su diverse variabili di ambiente personalizzate impostate in .env
e .env.development
.
Se ci si connette a un ambiente di authoring AEM, è necessario configurare il metodo di autenticazione corrispondente.
Condivisione delle risorse tra le origini (CORS)
Questa applicazione React si basa su una configurazione CORS basata su AEM in esecuzione nell'ambiente AEM di destinazione e presuppone che l'app React sia in esecuzione su http://localhost:3000
in modalità di sviluppo. Consulta ladocumentazione sulla distribuzione headless dell'AEM per ulteriori informazioni su come impostare e configurare CORS.