AEM GraphQL API,用于内容片段

了解如何将Adobe Experience Manager(AEM)中的内容片段用作AEM GraphQL API的Cloud Service,实现无外设内容投放。

AEM作为Cloud ServiceGraphQL API与内容片段一起使用,这在很大程度上是基于标准的开放源GraphQL API。

使用AEM中的GraphQL API,可以在无外设CMS实施中将内容片段高效投放到JavaScript客户端:

  • 避免像REST那样迭代API请求,
  • 确保投放仅限于具体要求,
  • 允许批量投放渲染所需的具体内容,作为对单个API查询的响应。
注意

GraphQL当前用于Adobe Experience Manager(AEM)中的两个(单独)方案作为Cloud Service:

GraphQL API

GraphQL是:

  • "…用于API的查询语言和用于使用现有数据实现这些查询的运行时。 GraphQL提供了对API中数据的完整而易于理解的描述,使客户能够确切地询问他们需要什么,而无需做更多工作,使API随着时间推移更加易于开发,并支持功能强大的开发人员工具。"。

    请参阅GraphQL.org

  • "…灵活的API层的开放规范。 将GraphQL置于现有后端之上,以比以往更快的速度构建产品……."。

    请参阅浏览GraphQL

  • "。…一种数据查询语言和规范,由Facebook于2012年在内部开发,后于2015年公开开发。它为基于REST的体系结构提供了一种替代方法,目的是提高开发者的工作效率并最大限度地减少数据传输量。 GraphQL由数百个不同规模的组织用于生产……"

    请参阅GraphQL Foundation

有关GraphQL API的更多信息,请参阅以下部分(包括许多其他资源):

用于AEM实施的GraphQL基于标准GraphQL Java库。 请参阅:

GraphQL术语

GraphQL使用以下功能:

有关详细信息,请参阅(GraphQL.org)GraphQL简介,包括最佳实践

GraphQL查询类型

通过GraphQL,您可以执行查询以返回以下任一项:

您还可以执行:

注意

可以使用GraphiQL IDE测试和调试GraphQL查询。

AEM Endpoint的GraphQL

endpoint是用于访问AEM的GraphQL的路径。 使用此路径,您(或您的应用程序)可以:

  • 访问GraphQL模式,
  • 发送您的GraphQL查询,
  • 接收响应(对您的GraphQL查询)。

AEM中有两种类型的端点:

  • 全局
    • 可供所有站点使用。
    • 此端点可以使用所有站点配置(在配置浏览器中定义)中的所有内容片段模型。
    • 如果在站点配置之间应共享任何内容片段模型,则应在全局站点配置下创建这些模型。
  • 站点配置:
    • 对应于站点配置,如配置浏览器中定义。
    • 特定于指定的站点/项目。
    • 特定于站点配置的终结点将使用该特定站点配置的内容片段模型与全局站点配置的内容片段模型一起使用。
注意

内容片段编辑器允许一个站点配置的内容片段引用另一个站点配置的内容片段(通过策略)。

在这种情况下,并非所有内容都可以使用特定于站点配置的端点进行检索。

内容作者应控制此方案;例如,考虑将共享内容片段模型置于全局站点配置下可能会很有用。

GraphQL for AEM全局端点的存储库路径为:

/content/cq:graphql/global/endpoint

您的应用程序可在请求URL中使用以下路径:

/content/_cq_graphql/global/endpoint.json

要为AEM的GraphQL启用端点,您需要:

启用GraphQL端点

要启用GraphQL端点,您首先需要具有相应的配置。 请参阅内容片段 — 配置浏览器

注意

如果未启用对内容片段模型的使用,则​创建​选项将不可用。

要启用相应的端点,请执行以下操作:

  1. 导航到​工具站点,然后选择​图形QL

  2. 选择​创建

  3. 将打开​新建GraphQL Endpoint​对话框。 您可以在此处指定:

    • 名称:端点的名称;您可以输入任何文本。
    • 使用GraphQL模式:使用下拉列表选择所需的站点/项目。
    注意

    对话框中显示以下警告:

    • 如果不对 GraphQL 端点仔细管理,则可能会带来数据安全和性能问题。请确保在创建端点后设置适当的权限。
  4. 使用​创建​进行确认。

  5. 后续步骤​对话框将提供指向安全控制台的直接链接,以便您能够确保新创建的端点具有适当的权限。

    注意

    每个人都可以访问该端点。 这可能会引起安全问题,因为GraphQL查询可能会对服务器施加大负载。

    您可以在端点上设置与用例相适应的ACL。

发布GraphQL端点

选择新端点并选择​发布,使其在所有环境中都完全可用。

注意

每个人都可以访问该端点。

在发布实例中,这可能会引起安全问题,因为GraphQL查询可能会对服务器施加大负载。

必须在端点上设置与用例相适应的ACL。

GraphiQL接口

标准GraphiQL接口的实现可与AEM GraphQL一起使用。 可以与AEM🔗一起安装。

注意

GraphiQL绑定了全局端点(对于特定的站点配置,它不与其他端点一起使用)。

此界面允许您直接输入和测试查询。

例如:

  • http://localhost:4502/content/graphiql.html

它提供语法高亮显示、自动完成、自动建议等功能,以及历史记录和在线文档:

GraphiQL接

安装AEM GraphiQL接口

GraphiQL用户界面可安装在AEM上并包含专用包:GraphiQL内容包v0.0.6(2021.3)包。

创作和发布环境的用例

用例取决于AEM作为Cloud Service环境的类型:

  • 发布环境;:

    • 查询JS应用程序数据(标准用例)
  • 创作环境;:

    • 查询数据用于“内容管理目的”:
      • AEM中作为Cloud Service的GraphQL当前是只读API。
      • REST API可用于CR(u)D操作。

权限

这些权限是访问资产所需的权限。

模式生成

GraphQL是强类型API,这意味着数据必须按照类型清晰地结构化和组织。

GraphQL规范提供了有关如何创建用于查询特定实例上的数据的强大API的一系列指南。 为此,客户端需要获取模式,其中包含查询所需的所有类型。

对于“内容片段”,GraphQL模式(结构和类型)基于​Enabled 内容片段模型及其数据类型。

注意

所有GraphQL模式(从​已启用​的内容片段模型派生)均可通过GraphQL端点读取。

这意味着您需要确保没有敏感数据可用,因为这些数据可能会以这种方式泄露;例如,这包括在模型定义中可能作为字段名称显示的信息。

例如,如果用户创建了名为Article的内容片段模型,则AEM会生成类型为ArticleModel的对象article。 此类型中的字段与模型中定义的字段和数据类型相对应。

  1. 内容片段模型:

    与GraphQLContent片段模型一起使

  2. 相应的GraphQL模式(从GraphiQL自动文档输出):
    基于内容片段模型的GraphQL模式基

    这表明生成的类型ArticleModel包含多个字段

    • 其中三个由用户控制:authormainreferencearticle

    • 其他字段由AEM自动添加,表示提供特定内容片段相关信息的有用方法;在此示例中,_path_metadata_variations。 这些帮助字段标有前面的_,以区分用户定义的内容和自动生成的内容。

  3. 在用户基于文章模型创建内容片段后,可以通过GraphQL进行询问。 有关示例,请参阅示例查询(基于示例内容片段结构,以与GraphQL一起使用)。

在GraphQL for AEM中,模式是灵活的。 这意味着每次创建、更新或删除内容片段模型时,都会自动生成该片段。 在更新内容片段模型时,数据模式缓存也会刷新。

站点图形QL服务监听(在后台)对内容片段模型所做的任何修改。 检测到更新时,只会重新生成模式的该部分。 这种优化节省了时间并提供了稳定性。

例如,如果:

  1. 安装包含Content-Fragment-Model-1Content-Fragment-Model-2:

    1. 将生成Model-1Model-2的GraphQL类型。
  2. 然后修改Content-Fragment-Model-2:

    1. 只有Model-2 GraphQL类型会更新。

    2. Model-1将保持不变。

注意

当您希望通过REST api或以其他方式对内容片段模型进行批量更新时,请务必注意这一点。

模式通过与GraphQL查询相同的端点进行服务,客户端处理以扩展名GQLschema调用模式的事实。 例如,对/content/cq:graphql/global/endpoint.GQLschema执行简单的GET请求将导致输出具有Content-type的模式:text/x-graphql-schema;charset=iso-8859-1

模式生成 — 未发布的模型

嵌套内容片段时,父内容片段模型可能已发布,但引用的模型不会发布。

注意

AEM UI可防止这种情况发生,但如果以编程方式或通过内容包进行发布,则可能会发生这种情况。

发生这种情况时,AEM会为父内容片段模型生成​不完整​模式。 这意味着从模式中删除依赖于未发布的模型的片段引用。

字段

在该模式中,有两个基本类别的单个字段:

  • 生成的字段。

    选择字段类型用于根据您配置内容片段模型的方式创建字段。 字段名称取自​数据类型​的​属性名称​字段。

    • 还有​Render As​属性要考虑,因为用户可以配置某些数据类型;例如,作为单行文本或多字段。
  • AEM的GraphQL还生成许多帮助字段

    它们用于标识内容片段或获取有关内容片段的更多信息。

字段类型

GraphQL for AEM支持列表类型。 所有支持的内容片段模型数据类型和相应的GraphQL类型均表示:

内容片段模型 — 数据类型 图形QL类型 描述
单行文本 字符串,[字符串] 用于简单字符串,如作者姓名、位置名称等。
多行文本 字符串 用于输出文本,如文章的正文
数字 浮点,[浮点] 用于显示浮点数和正则数
布尔型 布尔型 用于显示复选→框的简单true/false语句
日期和时间 日历 用于以ISO 8086格式显示日期和时间。 根据所选的类型,AEM GraphQL中有三种可用方式:onlyDateonlyTimedateTime
枚举 String 用于从创建模型时定义的列表选项中显示选项
标记 [String] 用于显示表示AEM中使用的标记的字符串列表
内容引用 字符串 用于在AEM中显示指向另一个资产的路径
片段引用 模型类型 用于引用某个“模型类型”的其他“内容片段”(在创建模型时定义)

帮助字段

除了用户生成字段的数据类型外,GraphQL for AEM还生成许多​helper​字段,以帮助识别内容片段或提供有关内容片段的其他信息。

路径

路径字段用作GraphQL中的标识符。 它表示AEM存储库内的内容片段资产的路径。 我们选择它作为内容片段的标识符,因为它:

  • 在AEM中是独一无二的,
  • 很容易被取走。

以下代码将显示基于内容片段模型Person创建的所有内容片段的路径。

{
  personList {
    items {
      _path
    }
  }
}

要检索特定类型的单个内容片段,您还需要首先确定其路径。 例如:

{
  personByPath(_path: "/content/dam/path/to/fragment/john-doe") {
    item {
      _path
      firstName
      name
    }
  }
}

请参阅示例查询 — 单个特定城市片段

元数据

通过GraphQL,AEM还公开内容片段的元数据。 元数据是描述内容片段的信息,例如内容片段的标题、缩略图路径、内容片段的描述、创建日期等。

由于元数据是通过模式编辑器生成的,因此没有特定的结构,因此实现了TypedMetaData GraphQL类型以公开内容片段的元数据。 TypedMetaData 显示按以下标量类型分组的信息:

字段
stringMetadata:[StringMetadata]!
stringArrayMetadata:[StringArrayMetadata]!
intMetadata:[IntMetadata]!
intArrayMetadata:[IntArrayMetadata]!
floatMetadata:[FloatMetadata]!
floatArrayMetadata:[FloatArrayMetadata]!
booleanMetadata:[BooleanMetadata]!
booleanArrayMetadata:[booleanArrayMetadata]!
calendarMetadata:[CalendarMetadata]!
calendarArrayMetadata:[CalendarArrayMetadata]!

每个标量类型表示单个名称 — 值对或名称 — 值对数组,其中该对的值是其分组的类型。

例如,如果您要检索内容片段的标题,我们知道此属性是String属性,因此我们将查询所有String Metadata:

要查询元数据:

{
  personByPath(_path: "/content/dam/path/to/fragment/john-doe") {
    item {
      _path
      _metadata {
        stringMetadata {
          name
          value
        }
      }
    }
  }
}

如果您视图“生成的GraphQL”模式,则可以视图所有元数据GraphQL类型。 所有型号类型具有相同的TypedMetaData

注意

普通元数据与数组元数据的区别
请记住,StringMetadataStringArrayMetadata都引用存储库中存储的内容,而不是如何检索它们。

因此,例如,通过调用stringMetadata字段,您将收到存储在存储库中的所有元数据的String数组,如果调用stringArrayMetadata,您将收到存储在存储库中的所有元数据的String[]数组。

请参阅元数据示例查询-列表标题为GB的奖项的元数据。

变量

_variations字段已实现,以简化查询内容片段所具有的变量。 例如:

{
  personByPath(_path: "/content/dam/path/to/fragment/john-doe") {
    item {
      _variations
    }
  }
}

请参阅示例查询 — 所有具有命名变量的城市

GraphQL变量

GraphQL允许将变量放置在查询中。 有关详细信息,请参阅变量的GraphQL文档。

例如,要获取具有特定变量的Article类型的所有内容片段,可以在GraphiQL中指定变量variation

GraphQL变

### query
query GetArticlesByVariation($variation: String!) {
    articleList(variation: $variation) {
        items {
            _path
            author
        }
    }
}
 
### in query variables
{
    "variation": "uk"
}

GraphQL指令

在GraphQL中,可以根据变量(称为GraphQL指令)更改查询。

例如,您可以根据变量includePrice将所有AdventureModels的查询包含adventurePrice字段。

GraphQL指

### query
query GetAdventureByType($includePrice: Boolean!) {
  adventureList {
    items {
      adventureTitle
      adventurePrice @include(if: $includePrice)
    }
  }
}
 
### in query variables
{
    "includePrice": true
}

筛选

您还可以在GraphQL查询中使用筛选来返回特定数据。

过滤使用基于逻辑运算符和表达式的语法。

例如,以下(基本)查询过滤器名为JobsSmith的所有人员:

query {
  personList(filter: {
    name: {
      _logOp: OR
      _expressions: [
        {
          value: "Jobs"
        },
        {
          value: "Smith"
        }
      ]
    }
  }) {
    items {
      name
      firstName
    }
  }
}

有关更多示例,请参阅:

GraphQL for AEM — 扩展摘要

使用GraphQL for AEM的查询的基本操作符合标准的GraphQL规范。 对于具有AEM的GraphQL查询,有以下几个扩展:

持久查询(缓存)

在准备具有查询请求的GET后,可以使用HTTP缓存或CDN缓存的POST请求执行该请求。

这是必需的,因为POST查询通常不进行缓存,如果将查询作为参数使用,则参数对于HTTP服务和中间产品而言变得过大的风险很大。

持久查询必须始终使用与相应的Sites配置相关的端点;这样,他们就可以使用其中一种或两种方式:

  • 全局配置和端点
    查询可以访问所有内容片段模型。
  • 特定站点配置和端点
    为特定站点配置创建持久查询需要相应的站点配置特定端点(以提供对相关内容片段模型的访问)。
    例如,要为WKND站点配置专门创建持久查询,必须提前创建相应的WKND特定站点配置和WKND特定端点。
注意

有关详细信息,请参阅在配置浏览器中启用内容片段功能

需要为相应的站点配置启用​GraphQL持久查询

例如,如果存在名为my-query的特定查询,它使用站点配置my-conf中的模型my-model:

  • 您可以使用my-conf特定端点创建查询,然后查询将保存为:
    /conf/my-conf/settings/graphql/persistentQueries/my-query
  • 您可以使用global端点创建相同的查询,但随后查询将保存为:
    /conf/global/settings/graphql/persistentQueries/my-query
注意

这是两种不同的查询 — 保存在不同的路径下。

他们恰巧使用了相同的模型 — 但是通过不同的端点。

以下是保持给定查询所需的步骤:

  1. 将查询放置到新的端点URL /graphql/persist.json/<config>/<persisted-label>来准备。

    例如,创建持久查询:

    $ curl -X PUT \
        -H 'authorization: Basic YWRtaW46YWRtaW4=' \
        -H "Content-Type: application/json" \
        "http://localhost:4502/graphql/persist.json/wknd/plain-article-query" \
        -d \
    '{
      articleList {
        items{
            _path
            author
            main {
                json
            }
        }
      }
    }'
    
  2. 此时,请检查响应。

    例如,检查成功与否:

    {
      "action": "create",
      "configurationName": "wknd",
      "name": "plain-article-query",
      "shortPath": "/wknd/plain-article-query",
      "path": "/conf/wknd/settings/graphql/persistentQueries/plain-article-query"
    }
    
  3. 然后,可以通过获取URL /graphql/execute.json/<shortPath>来重播保留的查询。

    例如,使用持久查询:

    $ curl -X GET \
        http://localhost:4502/graphql/execute.json/wknd/plain-article-query
    
  4. 通过将POST更新到现有查询路径来更新持续查询。

    例如,使用持久查询:

    $ curl -X POST \
        -H 'authorization: Basic YWRtaW46YWRtaW4=' \
        -H "Content-Type: application/json" \
        "http://localhost:4502/graphql/persist.json/wknd/plain-article-query" \
        -d \
    '{
      articleList {
        items{
            _path
            author
            main {
                json
            }
          referencearticle {
            _path
          }
        }
      }
    }'
    
  5. 创建包装的纯查询。

    例如:

    $ curl -X PUT \
        -H 'authorization: Basic YWRtaW46YWRtaW4=' \
        -H "Content-Type: application/json" \
        "http://localhost:4502/graphql/persist.json/wknd/plain-article-query-wrapped" \
        -d \
    '{ "query": "{articleList { items { _path author main { json } referencearticle { _path } } } }"}'
    
  6. 使用缓存控件创建包装式纯查询。

    例如:

    $ curl -X PUT \
        -H 'authorization: Basic YWRtaW46YWRtaW4=' \
        -H "Content-Type: application/json" \
        "http://localhost:4502/graphql/persist.json/wknd/plain-article-query-max-age" \
        -d \
    '{ "query": "{articleList { items { _path author main { json } referencearticle { _path } } } }", "cache-control": { "max-age": 300 }}'
    
  7. 使用参数创建持续查询:

    例如:

    $ curl -X PUT \
        -H 'authorization: Basic YWRtaW46YWRtaW4=' \
        -H "Content-Type: application/json" \
        "http://localhost:4502/graphql/persist.json/wknd/plain-article-query-parameters" \
        -d \
    'query GetAsGraphqlModelTestByPath($apath: String!, $withReference: Boolean = true) {
      articleByPath(_path: $apath) {
        item {
          _path
            author
            main {
            plaintext
            }
            referencearticle @include(if: $withReference) {
            _path
            }
          }
        }
      }'
    
  8. 使用参数执行查询。

    例如:

    $ curl -X POST \
        -H 'authorization: Basic YWRtaW46YWRtaW4=' \
        -H "Content-Type: application/json" \
        "http://localhost:4502/graphql/execute.json/wknd/plain-article-query-parameters;apath=%2fcontent2fdam2fwknd2fen2fmagazine2falaska-adventure2falaskan-adventures;withReference=false"
    
    $ curl -X GET \
        "http://localhost:4502/graphql/execute.json/wknd/plain-article-query-parameters;apath=%2fcontent2fdam2fwknd2fen2fmagazine2falaska-adventure2falaskan-adventures;withReference=false"
    
  9. 要在发布时执行查询,需要复制相关的持久树

    • 使用POST进行复制:

      $curl -X POST   http://localhost:4502/bin/replicate.json \
        -H 'authorization: Basic YWRtaW46YWRtaW4=' \
        -F path=/conf/wknd/settings/graphql/persistentQueries/plain-article-query \
        -F cmd=activate
      
    • 使用包:

      1. 创建新包定义。
      2. 包括配置(例如/conf/wknd/settings/graphql/persistentQueries)。
      3. 构建包。
      4. 复制包。
    • 使用复制/分发工具。

      1. 转到“分发”工具。
      2. 为配置选择树激活(例如/conf/wknd/settings/graphql/persistentQueries)。
    • 使用工作流(通过工作流启动器配置):

      1. 定义一个工作流启动器规则,用于执行将在不同事件(例如,创建、修改等)上复制配置的工作流模型。
  10. 查询配置在发布后,同样的原则也适用,只需使用发布端点即可。

    注意

    对于匿名访问,系统假定ACL允许“所有人”访问查询配置。

    如果情况并非如此,它将无法执行。

    注意

    需要对URL中的任何分号(";")进行编码。

    例如,与执行持久查询的请求一样:

    curl -X GET \ "http://localhost:4502/graphql/execute.json/wknd/plain-article-query-parameters%3bapath=%2fcontent2fdam2fwknd2fen2fmagazine2falaska-adventure2falaskan-adventures;withReference=false"
    

从外部网站查询GraphQL端点

要从外部网站访问GraphQL端点,您需要配置:

CORS过滤器

注意

有关AEM中CORS资源共享策略的详细概述,请参阅了解跨来源资源共享(CORS)

要访问GraphQL端点,必须在客户Git存储库中配置CORS策略。 为此,可为所需端点添加适当的OSGi CORS配置文件。

此配置必须指定必须授予访问权限的受信任的网站来源alloworiginalloworiginregexp

例如,要授予对https://my.domain的GraphQL端点和持久查询端点的访问权,可以使用:

{
  "supportscredentials":true,
  "supportedmethods":[
    "GET",
    "HEAD",
    "POST"
  ],
  "exposedheaders":[
    ""
  ],
  "alloworigin":[
    "https://my.domain"
  ],
  "maxage:Integer":1800,
  "alloworiginregexp":[
    ""
  ],
  "supportedheaders":[
    "Origin",
    "Accept",
    "X-Requested-With",
    "Content-Type",
    "Access-Control-Request-Method",
    "Access-Control-Request-Headers"
  ],
  "allowedpaths":[
    "/content/_cq_graphql/global/endpoint.json",
    "/graphql/execute.json/.*"
  ]
}

如果已配置端点的虚路径,则还可在allowedpaths中使用它。

推荐人过滤器

除了CORS配置之外,还必须配置推荐人过滤器以允许从第三方主机访问。

通过添加相应的OSGi推荐人过滤器配置文件来完成此操作,该配置文件:

  • 指定受信任的网站主机名;allow.hostsallow.hosts.regexp,
  • 授予对此主机名的访问权限。

例如,要授予推荐人my.domain的请求访问权限,您可以:

{
    "allow.empty":false,
    "allow.hosts":[
      "my.domain"
    ],
    "allow.hosts.regexp":[
      ""
    ],
    "filter.methods":[
      "POST",
      "PUT",
      "DELETE",
      "COPY",
      "MOVE"
    ],
    "exclude.agents.regexp":[
      ""
    ]
}
注意

客户仍有责任:

  • 仅授予对受信任域的访问权限
  • 确保没有暴露任何敏感信息
  • 不使用通配符[*]语法;这既将禁用对GraphQL端点的经过身份验证的访问,也会将其呈现给全世界。
注意

所有GraphQL 模式(派生自​已启用​的内容片段模型)均可通过GraphQL端点读取。

这意味着您需要确保没有敏感数据可用,因为这些数据可能会以这种方式泄露;例如,这包括在模型定义中可能作为字段名称显示的信息。

身份验证

请参阅内容片段上的远程AEM GraphQL查询身份验证

常见问题解答

出现的问题:

  1. :“AEM的GraphQL API与查询 Builder API有何不同?

    • :“AEM GraphQL API优惠对JSON输出的完全控制,是查询内容的行业标准。展望未来, AEM计划投资于AEM GraphQL API。"

教程 — AEM无外设和GraphQL快速入门

正在寻找实践教程? 查看无外设和GraphQL入门教程,该教程说明了如何在无外设CMS场景中使用AEM GraphQL API构建和公开内容并由外部应用程序使用。

On this page

Adobe Maker Awards Banner

Time to shine!

Apply now for the 2021 Adobe Experience Maker Awards.

Apply now
Adobe Maker Awards Banner

Time to shine!

Apply now for the 2021 Adobe Experience Maker Awards.

Apply now