客户端应用程序集成

在上一章中,您使用GraphiQL Explorer创建和更新了持久查询。

本章将指导您完成以下步骤:使用现有​ React组件 ​中的HTTPGET请求,将持久查询与WKND客户端应用程序(也称为WKND应用程序)集成。 它还提供了运用AEM Headless学习经验的一个可选挑战,编码专业知识以增强WKND客户端应用程序。

先决条件 prerequisites

本文档是多部分教程的一部分。 在继续本章之前,请确保已完成前几章。 WKND客户端应用程序连接到AEM发布服务,因此您​ 将以下内容发布到AEM发布服务 ​很重要。

  • 项目配置
  • GraphQL 端点
  • 内容片段模型
  • 创作的内容片段
  • GraphQL持久查询

本章中的​ IDE屏幕截图来自Visual Studio Code

第1-4章解决方案包(可选) solution-package

可以安装一个解决方案包,用于完成第1-4章的AEM UI中的步骤。 如果前面的章节已完成,则此包​ 不需要

  1. 下载Advanced-GraphQL-Tutorial-Solution-Package-1.2.zip
  2. 在AEM中,导航到​ 工具 > 部署 > ​以访问​ 包管理器
  3. 上载并安装在上一步中下载的软件包(zip文件)。
  4. 将包复制到AEM Publish服务

目标 objectives

在本教程中,您将了解如何使用AEM Headless Client for JavaScript将持久查询请求集成到示例WKND GraphQL React应用程序中。

克隆并运行示例客户端应用程序 clone-client-app

为加速教程,提供了一个入门版React JS应用程序。

  1. 克隆adobe/aem-guides-wknd-graphql存储库:

    code language-shell
    $ git clone git@github.com:adobe/aem-guides-wknd-graphql.git
    
  2. 编辑aem-guides-wknd-graphql/advanced-tutorial/.env.development文件并将REACT_APP_HOST_URI设置为指向您的目标AEM发布服务。

    如果连接到作者实例,请更新身份验证方法。

    code language-plain
    # 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=
    

    React应用程序开发环境

    note note
    NOTE
    上述说明用于将React应用程序连接到​ AEM Publish服务,而要连接到​ AEM Author服务,请为您的目标AEM as a Cloud Service环境获取本地开发令牌。
    还可以使用基本身份验证使用AEMaaCS SDK🔗将应用程序连接到本地作者实例。
  3. 打开终端并运行以下命令:

    code language-shell
    $ cd aem-guides-wknd-graphql/advanced-tutorial
    $ npm install
    $ npm start
    
  4. 新的浏览器窗口应在http://localhost:3000上加载

  5. 点按​ Camping > Yosemite Backpacking ​以查看Yosemite Backpacking冒险详细信息。

    Yosemite背包屏幕

  6. 打开浏览器的开发人员工具并检查XHR请求

    POSTGraphQL

    您应该会看到对GraphQL端点的GET请求,其中包含项目配置名称(wknd-shared)、持久查询名称(adventure-by-slug)、变量名称(slug)、值(yosemite-backpacking)和特殊字符编码。

IMPORTANT
如果您想了解为什么针对http://localhost:3000而不是针对AEM Publish Service域发出GraphQL API请求,请查看基础教程中的主题

查看代码

基础教程 — 构建使用AEM的GraphQL API的React应用程序步骤中,我们查看并增强了几个关键文件,以获得实践专业知识。 在增强WKND应用程序之前,请查看关键文件。

查看Adventures React组件

WKND React应用程序的主视图是所有冒险的列表,您可以根据​ 露营、骑自行车 ​等活动类型筛选这些冒险。 此视图由Adventures组件渲染。 以下是主要实施详细信息:

  • src/components/Adventures.js调用useAllAdventures(adventureActivity)挂接,其中adventureActivity参数为活动类型。

  • useAllAdventures(adventureActivity)挂接在src/api/usePersistedQueries.js文件中定义。 根据adventureActivity值,它确定要调用的持久查询。 如果不为null值,则调用wknd-shared/adventures-by-activity,否则获取所有可用的冒险wknd-shared/adventures-all

  • 挂接使用通过aemHeadlessClient.js将查询执行委派给AEMHeadless的主fetchPersistedQuery(..)函数。

  • 该挂接还仅从response.data?.adventureList?.items处的AEM GraphQL响应返回相关数据,从而允许Adventures React视图组件独立于父JSON结构。

  • 成功执行查询后,Adventures.js中的AdventureListItem(..)渲染函数将添加HTML元素以显示​ 图像、行程长度、价格和标题 ​信息。

查看AdventureDetail React组件

AdventureDetail React组件呈现冒险的详细信息。 以下是主要实施详细信息:

  • src/components/AdventureDetail.js调用useAdventureBySlug(slug)挂接,此处slug参数是查询参数。

  • 如上所述,useAdventureBySlug(slug)挂接在src/api/usePersistedQueries.js文件中定义。 它通过aemHeadlessClient.js委托给AEMHeadless来调用wknd-shared/adventure-by-slug持久查询。

  • 成功执行查询后,AdventureDetail.js中的AdventureDetailRender(..)渲染函数将添加HTML元素以显示冒险详细信息。

增强代码

使用adventure-details-by-slug持久查询

在上一章中,我们创建了adventure-details-by-slug持久查询,它提供了其他冒险信息,例如​ 位置、讲师团队和管理员。 让我们将adventure-by-slug替换为adventure-details-by-slug持久查询以呈现此附加信息。

  1. 打开src/api/usePersistedQueries.js

  2. 找到函数useAdventureBySlug()并将查询更新为

 ...

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

 ...

显示附加信息

  1. 若要显示其他冒险信息,请打开src/components/AdventureDetail.js

  2. 找到函数AdventureDetailRender(..)并将返回函数更新为

    code language-javascript
    ...
    
    return (<>
        <h1 className="adventure-detail-title">{title}</h1>
        <div className="adventure-detail-info">
    
            <LocationInfo {...location} />
    
            ...
    
            <Location {...location} />
    
            <Administrator {...administrator} />
    
            <InstructorTeam {...instructorTeam} />
    
        </div>
    </>);
    
    ...
    
  3. 还可定义相应的渲染函数:

    位置信息

    code language-javascript
    function LocationInfo({name}) {
    
        if (!name) {
            return null;
        }
    
        return (
            <>
                <div className="adventure-detail-info-label">Location</div>
                <div className="adventure-detail-info-description">{name}</div>
            </>
        );
    
    }
    

    位置

    code language-javascript
    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>
            </>);
    }
    

    讲师团队

    code language-javascript
    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>
            </>);
    }
    

    管理员

    code language-javascript
    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>
            </>);
    }
    

定义新样式

  1. 打开src/components/AdventureDetail.scss并添加以下类定义

    code language-css
    .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;
    }
    
TIP
更新后的文件位于​ AEM Guides WKND - GraphQL ​项目下,请参阅高级教程部分。

完成上述增强功能后,WKND应用程序如下所示,浏览器的开发人员工具显示adventure-details-by-slug持久查询调用。

增强的WKND应用程序

增强质询(可选)

WKND React应用程序的主视图允许您根据活动类型(如​ 露营、循环)筛选这些冒险。 但是,WKND业务团队希望拥有基于​ 位置 ​的额外筛选功能。 要求包括

  • 在WKND应用程序的主视图中,在左上角或右上角添加​ 位置 ​筛选图标。
  • 单击​ 位置 ​筛选图标应显示位置列表。
  • 单击列表中的所需位置选项应仅显示匹配的冒险。
  • 如果只有一个匹配的探险,则会显示“探险详细信息”视图。

恭喜

恭喜!您现在已完成集成,并将持久查询实施到示例WKND应用程序中。

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