Application React react-app

[AEM Headless as a Cloud Service]{class="badge informative"}

Découvrez les fonctionnalités découplées d’Adobe Experience Manager (AEM) grâce aux exemples d’applications. Cette application React explique comment interroger du contenu à l’aide des API GraphQL d’AEM en utilisant des requêtes persistantes. Le client AEM Headless pour JavaScript est utilisé pour exécuter les requêtes persistantes GraphQL qui alimentent l’application.

Application React avec AEM Headless.

Afficher le code source sur GitHub

Un tutoriel détaillé complet décrivant comment cette application React a été créée est disponible.

Prérequis prerequisites

Les outils suivants doivent être installés localement :

Configuration requise d’AEM

L’application React fonctionne avec les options de déploiement AEM suivantes. Tous les déploiements nécessitent que la version v3.0.0 ou supérieure du site WKND soit installée.

L’application React est conçue pour se connecter à un environnement de Publication AEM, cependant, elle peut s’approvisionner en contenu auprès de l’environnement de création AEM si l’authentification est fournie dans la configuration de l’application React.

Utilisation

  1. Clonez le référentiel adobe/aem-guides-wknd-graphql :

    code language-shell
    $ git clone git@github.com:adobe/aem-guides-wknd-graphql.git
    
  2. Modifiez le fichier aem-guides-wknd-graphql/react-app/.env.development et définissez REACT_APP_HOST_URI de manière à pointer vers votre cible AEM.

    Mettez à jour la méthode d’authentification si vous vous connectez à une instance de création.

    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
    
  3. Ouvrez un terminal et exécutez les commandes :

    code language-shell
    $ cd aem-guides-wknd-graphql/react-app
    $ npm install
    $ npm start
    
  4. Une nouvelle fenêtre de navigateur doit s’afficher dans http://localhost:3000.

  5. Une liste des Adventures du site de référence WKND doit s’afficher sur l’application.

Le code

Vous trouverez ci-dessous un résumé sur la façon dont l’application React est construite, comment elle se connecte à AEM Headless pour récupérer le contenu à l’aide de requêtes persistantes GraphQL, et comment ces données sont présentées. Le code complet se trouve sur GitHub.

Requêtes persistantes

Conformément aux bonnes pratiques d’AEM Headless, l’application React utilise les requêtes GraphQL persistantes d’AEM pour interroger les données de l’Adventure. L’application utilise deux requêtes persistantes :

  • La requête persistante wknd/adventures-all, qui renvoie toutes les Adventures dans AEM avec un ensemble abrégé de propriétés. Cette requête persistante génère la liste des Adventures de la vue initiale.
# 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
        }
      }
    }
  }
}
  • La requête persistante wknd/adventure-by-slug, qui renvoie une seule Adventure par slug (propriété personnalisée qui identifie de manière unique une Adventure) avec un ensemble complet de propriétés. Cette requête persistante alimente les vues détaillées de l’Adventure.
# 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
      }
    }
  }
}

Exécuter la requête persistante GraphQL

Les requêtes persistantes d’AEM sont exécutées sur une requête HTTP GET et, par conséquent, le client AEM Headless pour JavaScript est utilisé pour exécuter les requêtes GraphQL persistantes par rapport à AEM et charger le contenu de l’Adventure dans l’application.

Chaque requête persistante possède un hook useEffect React correspondant dans src/api/usePersistedQueries.js, qui appelle de manière asynchrone le point d’entrée de requête persistante HTTP GET d’AEM et renvoie les données des Adventures.

Chaque fonction appelle à son tour la aemHeadlessClient.runPersistedQuery(...), afin d’exécuter la requête GraphQL persistante.

// 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 };
}

Vues

L’application React utilise deux vues pour présenter les données de l’Adventure dans l’expérience web.

  • src/components/Adventures.js

    Elle appelle getAdventuresByActivity(..) à partir de src/api/usePersistedQueries.js et affiche les Adventures renvoyées dans une liste.

  • src/components/AdventureDetail.js

    Elle appelle getAdventureBySlug(..) en utilisant le paramètre slug transmis via la sélection des Adventures sur le composant Adventures et affiche les détails d’une seule Adventure.

Variables d’environnement

Plusieurs variables d’environnement sont utilisées pour se connecter à un environnement AEM. La valeur par défaut se connecte au service de publication AEM en cours d’exécution à l’adresse http://localhost:4503. Mettez à jour le fichier .env.development pour modifier la connexion d’AEM :

  • REACT_APP_HOST_URI=https://publish-p123-e456.adobeaemcloud.com : définissez sur l’hôte cible AEM.

  • REACT_APP_GRAPHQL_ENDPOINT=/content/graphql/global/endpoint.json : définissez le chemin d’accès du point d’entrée GraphQL. Ceci n’est pas utilisé par cette application React, qui utilise uniquement des requêtes persistantes.

  • REACT_APP_AUTH_METHOD= : méthode d’authentification préférée. Elle est facultative, aucune authentification n’est utilisée par défaut.

    • service-token : utilisez les informations d’identification du service pour obtenir un jeton d’accès sur AEM as a Cloud Service.
    • dev-token : utilisez un jeton de développement pour le développement local sur AEM as a Cloud Service.
    • basic : utilisez un nom d’utilisateur et un mot de passe pour le développement local sur l’instance locale de création d’AEM.
    • Laissez vide pour vous connecter à AEM sans authentification.
  • REACT_APP_AUTHORIZATION=admin:admin : définissez les informations d’identification d’authentification de base à utiliser lors de la connexion à un environnement de création AEM (pour le développement uniquement). Si vous vous connectez à un environnement de publication, ce paramètre n’est pas nécessaire.

  • REACT_APP_DEV_TOKEN : chaîne du jeton de développement. Pour vous connecter à une instance distante, en plus de l’authentification de base (user:pass), vous pouvez utiliser l’authentification du porteur avec le jeton de développement de la console Cloud.

  • REACT_APP_SERVICE_TOKEN : chemin d’accès au fichier d’informations d’identification du service. Pour vous connecter à une instance distante, l’authentification peut également être effectuée avec le jeton de service (téléchargez le fichier depuis la Developer Console).

Requêtes AEM proxy

Lors de l’utilisation du serveur de développement webpack (npm start), le projet repose sur une configuration du proxy utilisant http-proxy-middleware. Le fichier est configuré sur src/setupProxy.js et repose sur plusieurs variables d’environnement personnalisées définies sur .env et .env.development.

Si vous vous connectez à un environnement de création AEM, la méthode d’authentification correspondante doit être configurée.

Partage de ressources entre origines multiples (CORS)

Cette application React repose sur une configuration CORS basée sur AEM s’exécutant sur l’environnement AEM cible et suppose que l’application React s’exécute sur http://localhost:3000 en mode de développement. Consultez la documentation AEM sur le déploiement découplé pour plus d’informations sur les paramètres et la configuration de CORS.

recommendation-more-help
e25b6834-e87f-4ff3-ba56-4cd16cdfdec4