React アプリ

アプリケーション例は、Adobe Experience Manager(AEM) のヘッドレス機能を調べる優れた方法です。 この React アプリケーションは、永続化されたクエリを使用してAEM GraphQL API でコンテンツに対してクエリを実行する方法を示します。 AEM Headless Client for JavaScript は、アプリを強化するGraphQLの永続クエリを実行するために使用されます。

AEMヘッドレスを使用した React アプリ

次を表示: GitHub のソースコード

A 詳細な手順のチュートリアル この React アプリのビルドを使用する方法を説明します。

前提条件

以下のツールをローカルにインストールする必要があります。

AEM要件

React アプリケーションは、次のAEMデプロイメントオプションと連携します。 すべてのデプロイメントには、 WKND サイト v2.0.0 以降 をインストールします。

React アプリケーションは、 AEM パブリッシュ 環境で使用できますが、React アプリケーションの設定で認証が提供されている場合は、AEM オーサーからコンテンツをソース化できます。

使用方法

  1. のクローン adobe/aem-guides-wknd-graphql リポジトリ:

    $ git clone git@github.com:adobe/aem-guides-wknd-graphql.git
    
  2. を編集します。 aem-guides-wknd-graphql/react-app/.env.development ファイルとセット REACT_APP_HOST_URI をクリックして、ターゲットAEMを指定します。

    オーサーインスタンスに接続する場合は、認証方法を更新します。

    # 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
    
  3. ターミナルを開き、次のコマンドを実行します。

    $ cd aem-guides-wknd-graphql/react-app
    $ npm install
    $ npm start
    
  4. 新しいブラウザーウィンドウが読み込まれます。 http://localhost:3000

  5. WKND リファレンスサイトのアドベンチャーのリストがアプリケーションに表示される必要があります。

コード

GraphQLでの永続化されたクエリを使用してコンテンツを取得するために React アプリケーションが構築される方法、AEMヘッドレスに接続する方法、およびそのデータの表示方法の概要を次に示します。 完全なコードは、 GitHub.

永続クエリ

AEMヘッドレスのベストプラクティスに従い、React アプリケーションはAEM GraphQLで永続的なクエリを使用してアドベンチャーデータをクエリします。 アプリケーションでは、次の 2 つの永続クエリを使用します。

  • wknd/adventures-all 持続的なクエリで、AEM内のすべてのアドベンチャを簡潔なプロパティセットで返します。 この永続的なクエリは、初期ビューのアドベンチャーリストを駆動します。
# Retrieves a list of all adventures
{
    adventureList {
        items {
            _path
            slug
            title
            price
            tripLength
            primaryImage {
                ... on ImageRef {
                _path
                mimeType
                width
                height
                }
            }
        }
    }
}
  • wknd/adventure-by-slug 次の条件を満たす 1 つのアドベンチャーを返す永続クエリ slug 一連のプロパティを持つ(アドベンチャーを一意に識別するカスタムプロパティ)。 この永続的なクエリは、アドベンチャーの詳細表示を強化します。
# 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
      }
    }
  }
}

GraphQL永続クエリの実行

AEMで永続化されたクエリは HTTPGETを介して実行されるので、 JavaScript 用AEMヘッドレスクライアント永続的なGraphQLクエリの実行 AEMに対して貼り付け、アドベンチャーコンテンツをアプリに読み込みます。

永続化された各クエリには、対応する React が含まれます useEffect 引っ掛かる src/api/usePersistedQueries.jsを呼び出し、AEM HTTPGET持続クエリエンドポイントを非同期的に呼び出して、アドベンチャーデータを返します。

次に、各関数が aemHeadlessClient.runPersistedQuery(...)に設定し、永続化されたGraphQLクエリを実行します。

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

表示

React アプリケーションは、2 つのビューを使用して、Web エクスペリエンスにアドベンチャーデータを表示します。

  • src/components/Adventures.js

    呼び出し getAdventuresByActivity(..) から src/api/usePersistedQueries.js 返された冒険をリストに表示します。

  • src/components/AdventureDetail.js

    を呼び出します。 getAdventureBySlug(..) の使用 slug アドベンチャー選択経由で渡されるパラメーター Adventures コンポーネントを選択し、単一のアドベンチャーの詳細を表示します。

環境変数

複数 環境変数 を使用してAEM環境に接続します。 デフォルトでは、次の場所で実行されている AEM パブリッシュに接続します: http://localhost:4503. を更新します。 .env.development ファイルを編集し、AEM接続を変更します。

  • REACT_APP_HOST_URI=http://localhost:4502:AEM target host に設定
  • REACT_APP_GRAPHQL_ENDPOINT=/content/graphql/global/endpoint.json:GraphQLエンドポイントのパスを設定します。 このアプリは永続化されたクエリのみを使用するので、この React アプリでは使用されません。
  • REACT_APP_AUTH_METHOD=:推奨される認証方法。 オプション。デフォルトでは認証は使用されません。
    • service-token:サービス資格情報を使用してAEM as a Cloud Serviceのアクセストークンを取得する
    • dev-token:AEM as a Cloud Serviceのローカル開発に開発トークンを使用
    • basic:ローカル AEM オーサーとのローカル開発にユーザー/パスを使用
    • 認証なしでAEMに接続する場合は空白のままにします
  • REACT_APP_AUTHORIZATION=admin:admin:AEM オーサー環境に接続する場合に使用する基本認証資格情報を設定します(開発用のみ)。 パブリッシュ環境に接続する場合、この設定は不要です。
  • REACT_APP_DEV_TOKEN:開発トークン文字列。 リモートインスタンスに接続するには、基本認証 (user:pass) の横で、Cloud Console の DEV トークンで Bearer 認証を使用できます
  • REACT_APP_SERVICE_TOKEN:サービス資格情報ファイルのパス。 リモートインスタンスに接続する場合は、サービストークン(開発者コンソールからファイルをダウンロード)を使用して認証もおこなえます。

プロキシAEMリクエスト

WebPack 開発サーバーを使用する場合 (npm start) プロジェクトが プロキシ設定 using http-proxy-middleware. ファイルは次の場所に設定されています。 src/setupProxy.js とは、で設定された複数のカスタム環境変数を使用します。 .env および .env.development.

AEMオーサー環境に接続する場合、 認証方法を設定する必要があります.

クロスオリジンリソース共有 (CORS)

この React アプリケーションは、ターゲットAEM環境で実行されるAEMベースの CORS 設定に依存し、React アプリがで実行されると想定します。 http://localhost:3000 開発モードで。 この CORS 設定 は、 WKND サイト.

CORS 設定

このページ