持久 GraphQL 查询 persisted-graphql-queries
持久查询是创建并存储在 51黑料不打烊 Experience Manager (AEM) as a Cloud Service 服务器上的 GraphQL 查询。它们可以经客户端应用程序以 GET 请求方式请求。GET 请求的响应可以在 Dispatcher 和 CDN 层缓存,最终改进请求客户端应用程序的性能。这与标准的 GraphQL 查询不同,后者使用 POST 请求执行,而在 POST 请求中,无法轻松缓存响应。
GraphiQL IDE 在 AEM 中可供您开发、测试和持久您的 GraphQL 查询,然后再转移到您的生产环境。对于需要自定义的情况(例如,当自定义缓存时)可使用该 API;请参阅在如何使 GraphQL 查询持久中提供的 cURL 示例。
持久查询及端点 persisted-queries-and-endpoints
持久查询必须始终使用与相应 Sites 配置相关的端点,因此它们可以使用以下项之一或全部:
- 全球配置和端点
查询具有对所有内容片段模型的访问权限。 - 特定 Sites 配置和端点
为特定 Sites 配置创建持久查询需要对应的 Sites 配置特定的端点(用于提供对相关内容片段模型的访问权限)。
例如,要创建特定于 WKND Sites 配置的持久查询,必须预先创建对应的 WKND 特定的端点。
例如,如果存在名为 my-query 的特定查询,使用来自 Sites 配置 my-conf 的模型 my-model:
- 您可以使用
my-conf特定的端点创建查询,然后查询会保存如下:/conf/my-conf/settings/graphql/persistentQueries/my-query - 您可以使用
global端点创建相同的查询,但此后查询会保存如下:/conf/global/settings/graphql/persistentQueries/my-query
如何使 GraphQL 查询持久 how-to-persist-query
建议先在 AEM 作者环境中保留查询,然后将查询转移到 AEM 发布环境中,供应用程序使用。
有多种持久查询的方法,包括:
- GraphiQL IDE – 请参阅保存保留的查询(首选方法)
- cURL - 请查看以下示例
- 其他工具,包括
GraphiQL IDE 是 首选 ?保留查询的方法。使用 cURL 命令行工具使给定的查询持久:
-
使用 PUT 操作将查询放入新端点 URL
/graphql/persist.json/<config>/<persisted-label>来准备查询。例如,创建持久查询:
code language-shell $ 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 } } } }' -
此时,检查响应。
例如,检查是否成功:
code language-json { "action": "create", "configurationName": "wknd", "name": "plain-article-query", "shortPath": "/wknd/plain-article-query", "path": "/conf/wknd/settings/graphql/persistentQueries/plain-article-query" } -
然后,您可以通过对 URL
/graphql/execute.json/<shortPath>执行 GET 操作来请求持久查询。例如,使用持久查询:
code language-shell $ curl -X GET \ http://localhost:4502/graphql/execute.json/wknd/plain-article-query -
通过将持久查询 POST 到已经存在的查询路径来更新持久查询。
例如,使用持久查询:
code language-shell $ 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 } } } }' -
创建打包的简单查询。
例如:
code language-shell $ 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 } } } }"}' -
使用缓存控制创建打包的简单查询。
例如:
code language-shell $ 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 }}' -
使用参数创建持久查询:
例如:
code language-shell $ 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 } } } }'
如何执行持久查询 execute-persisted-query
要执行持久查询,客户端应用程序使用以下语法发出 GET 请求:
GET <AEM_HOST>/graphql/execute.json/<PERSISTENT_PATH>
其中 PERSISTENT_PATH 是保存持久查询的缩略路径。
-
例如,
wknd是配置名称,plain-article-query为持久查询的名称。要执行查询:code language-shell $ curl -X GET \ https://publish-p123-e456.adobeaemcloud.com/graphql/execute.json/wknd/plain-article-query -
使用参数执行查询。
note note NOTE 执行持久查询时,必须对查询变量和值进行正确地编码。 例如:
code language-xml $ curl -X GET \ "https://publish-p123-e456.adobeaemcloud.com/graphql/execute.json/wknd/plain-article-query-parameters%3Bapath%3D%2Fcontent%2Fdam%2Fwknd%2Fen%2Fmagazine%2Falaska-adventure%2Falaskan-adventures%3Bwithreference%3Dfalse请参阅使用查询变量以了解更多详细信息。
使用查询变量 query-variables
查询变量可与持久查询一起使用。使用变量名称和值将查询变量附加到以分号 (;) 为前缀的请求中。多个变量以分号分隔。
该模式如下所示:
<AEM_HOST>/graphql/execute.json/<PERSISTENT_QUERY_PATH>;variable1=value1;variable2=value2
例如,以下查询包含一个变量 activity 要根据活动值过滤列表,请执行以下操作:
query getAdventuresByActivity($activity: String!) {
adventureList (filter: {
adventureActivity: {
_expressions: [
{
value: $activity
}
]
}
}){
items {
_path
adventureTitle
adventurePrice
adventureTripLength
}
}
}
此查询可以保留在路径 wknd/adventures-by-activity下。要调用 Persisted 查询 activity=Camping,请求如下所示:
<AEM_HOST>/graphql/execute.json/wknd/adventures-by-activity%3Bactivity%3DCamping
UTF-8 编码 %3B 是 ; 的,%3D 是 = 的编码。查询变量和任何特殊字符必须正确编码才能执行持久查询。
使用查询变量 - 最佳实践 query-variables-best-practices
在查询中使用变量时,应遵循一些最佳做法:
-
编码
作为一般方法,始终建议对所有特殊字符进行编码;例如,;、=、?、&等等。 -
分号
使用多个变量(以分号分隔)的持久查询需要具有以下任一功能:- 编码的分号(
%3B);对 URL 进行编码也能达到此目的 - 或者在查询末尾添加一个分号
- 编码的分号(
-
CACHE_GRAPHQL_PERSISTED_QUERIES
什么时候CACHE_GRAPHQL_PERSISTED_QUERIES为 Dispatcher 启用,则包含/或者\其值中的字符在 Dispatcher 级别被编码两次。为了避免这种情况:-
在 Dispatcher 上启用
DispatcherNoCanonURL。
这将指示 Dispatcher 将原始 URL 转发到 AEM,从而防止重复编码。
但是此设置目前仅适用于vhost级别,因此如果你已经有 Dispatcher 配置来重写 URL(例如使用缩短的 URL 时),则可能需要单独的vhost用于持久查询 URL。 -
发送
/或者\未编码的字符。
调用持久查询 URL 时,确保所有/或者\字符在持久查询变量的值中仍未编码。note note NOTE 此选项仅建议用于 DispatcherNoCanonURL解决方案因某种原因无法实施。
-
-
CACHE_GRAPHQL_PERSISTED_QUERIES当为 Dispatcher 启用“
CACHE_GRAPHQL_PERSISTED_QUERIES”时,则变量值中不能使用字符“;”。
正在缓存您的持久查询 caching-persisted-queries
建议使用持久查询,因为可在 Dispatcher 和内容交付网络 (CDN) 层缓存此类查询,最终提高发出请求的客户端应用程序的性能。
默认情况下,AEM 将根据生存时间 (TTL) 定义使缓存失效。可通过以下参数定义这些 TTL。可通过多种方式访问这些参数,其名称因所使用的机制而异:
max-agecache-control : max-agecacheControlMaxAgegraphqlCacheControls-maxagesurrogate-control : max-agesurrogateControlMaxAgegraphqlSurrogateControlstale-while-revalidatesurrogate-control : stale-while-revalidatesurrogateControlStaleWhileRevalidategraphqlStaleWhileRevalidatestale-if-errorsurrogate-control : stale-if-errorsurrogateControlStaleIfErrorgraphqlStaleIfError创作实例 author-instances
创作实例的默认值为:
max-age: 60s-maxage: 60stale-while-revalidate: 86400stale-if-error: 86400
这些值:
-
无法被覆盖:
- 用 OSGi 配置覆盖
-
可被覆盖:
- 被使用 cURL 定义 HTTP 标头设置的请求覆盖;它应该包括适合
cache-control和/或surrogate-control的设置;有关示例,请参阅在持久查询级别管理缓存 - 如果在 GraphiQL IDE 的? 标头 ?对话框中指定值,则可覆盖
- 被使用 cURL 定义 HTTP 标头设置的请求覆盖;它应该包括适合
发布实例 publish-instances
发布实例的默认值为:
max-age: 60s-maxage: 7200stale-while-revalidate: 86400stale-if-error: 86400
这些值可被覆盖:
-
在持久查询级别覆盖;其中涉及在命令行界面中使用 cURL 将查询发布到 AEM 以及发布持久查询。
在 GraphiQL IDE 中管理 HTTP 缓存标头 http-cache-headers-graphiql-ide
GraphiQL IDE - 请参阅保存持久查询
在持久查询级别管理缓存 cache-persisted-query-level
其中涉及在命令行界面中使用 cURL 将查询发布到 AEM。
笔鲍罢(创建)方法的示例:
curl -u admin:admin -X PUT \
--url "http://localhost:4502/graphql/persist.json/wknd/plain-article-query-max-age" \
--header "Content-Type: application/json" \
--data '{ "query": "{articleList { items { _path author } } }", "cache-control": { "max-age": 300 }, "surrogate-control": {"max-age":600, "stale-while-revalidate":1000, "stale-if-error":1000} }'
笔翱厂罢(更新)方法的示例:
curl -u admin:admin -X POST \
--url "http://localhost:4502/graphql/persist.json/wknd/plain-article-query-max-age" \
--header "Content-Type: application/json" \
--data '{ "query": "{articleList { items { _path author } } }", "cache-control": { "max-age": 300 }, "surrogate-control": {"max-age":600, "stale-while-revalidate":1000, "stale-if-error":1000} }'
可以在创建时(PUT)或以后(例如,通过 POST 请求)设置 cache-control。在创建持久查询时,缓存控制是可选的,因为 AEM 可以提供默认值。有关使用 cURL 使查询持久的示例,请参阅如何使 GraphQL 查询持久。
使用 Cloud Manager 变量管理缓存 cache-cloud-manager-variables
可用 Cloud Manager 定义 Cloud Manager 环境变量以定义所需的值:
graphqlStaleIfErrorgraphqlSurrogateControl使用 OSGi 配置管理缓存 cache-osgi-configration
要全局管理缓存,您可以为? 持久查询服务配置配置 OSGi 设置。
发布实例的默认 OSGi 配置:
-
读取 Cloud Manager 变量(如果可用):
table 0-row-3 1-row-3 2-row-3 3-row-3 4-row-3 layout-auto OSGi 配置属性 读取此项 Cloud Manager 变量 cacheControlMaxAge读 graphqlCacheControlsurrogateControlMaxAge读 graphqlSurrogateControlsurrogateControlStaleWhileRevalidate读 graphqlStaleWhileRevalidatesurrogateControlStaleIfError读 graphqlStaleIfError -
如果不可用,OSGi 配置将使用发布实例的默认值。
配置查询响应代码 configuring-query-response-code
默认情况下,无论实际结果如何,PersistedQueryServlet在执行查询时都会发送200响应。
当持久查询中出现错误时,您可以为? 持久查询服务配置配置 OSGi 设置,以控制 /execute.json/persisted-query 端点是否返回更详细的状态代码。
字段 Respond with application/graphql-response+json (responseContentTypeGraphQLResponseJson) 可以根据需要定义:
-
false(默认值):
持久化查询成功与否无关紧要。Content-Type标头返回的是application/json,而/execute.json/persisted-query总是 ?返回状态代码200。 -
true:
返回的Content-Type是application/graphql-response+json,并且当运行持久查询时出现任何形式的错误,端点将返回适当的响应代码:table 0-row-2 1-row-2 2-row-2 3-row-2 4-row-2 代码 描述 200 成功响应 400 表示缺少标题,或者持久查询路径存在问题。例如:未指定配置名称、未指定后缀等。
参阅 故障排除 - 未配置 GraphQL 端点。404 未能找到所请求的资源。例如:Graphql 端点在服务器上不可用。
参阅 故障排除 - GraphQL 持久查询 URL 中缺少路径。500 内部服务器错误。例如:验证错误、持久性错误等。 note note NOTE 另请参阅 https://graphql.github.io/graphql-over-http/draft/#sec-Status-Codes
为应用程序使用的查询 URL 编码 encoding-query-url
对于应用程序,在构建查询变量时使用的任何特殊字符(即分号 (;)、等号 (=)、斜杠 /)才能使用相应的 UTF-8 编码。
例如:
curl -X GET \ "https://publish-p123-e456.adobeaemcloud.com/graphql/execute.json/wknd/adventure-by-path%3BadventurePath%3D%2Fcontent%2Fdam%2Fwknd%2Fen%2Fadventures%2Fbali-surf-camp%2Fbali-surf-camp"
URL 可以划分为以下部分:
/graphql/execute.json/wknd/adventure-by-path%3B; 的编码adventurePath%3D= 的编码%2F/ 的编码%2Fcontent%2Fdam...在纯文本中,请求 URI 如下所示:
/graphql/execute.json/wknd/adventure-by-path;adventurePath=/content/dam/wknd/en/adventures/bali-surf-camp/bali-surf-camp
要在客户端应用程序中使用持久查询,应使用 AEM headless 客户端 SDK 、 或 。Headless 客户端 SDK 将自动在请求中正确编码任何查询变量。
正在将持久查询转移到生产环境 transfer-persisted-query-production
应始终在 AEM 创作服务上创建持久查询,然后将其发布(复制)到 AEM 发布服务。通常,持久查询会在本地或开发环境等较低环境中创建和测试。然后,有必要将持久查询提升到更高级别的环境,最终在生产 AEM 发布环境中提供,以供客户端应用程序使用。
持久查询包
可以将持久查询构建在 AEM 程序包中。然后,可以在不同的环境中下载和安装 AEM 包。AEM 包也可以从 AEM 创作环境复制到 AEM 发布环境。
要创建包:
- 导航到? 工具 > 部署 > 包。
- 点击? 创建包 ?创建一个新包。这打开一个用于定义资源包的对话框。
- 在包定义对话框中,在? 常规 ?下输入? 名称,如“飞办苍诲-辫别谤蝉颈蝉迟别苍迟-辩耻别谤颈别蝉”。
- 输入版本号,如“1.0”。
- 在? 过滤器 ?下添加新的? 过滤器。使用路径查找器选择
persistentQueries文件夹。例如,对于wknd配置,完整路径为/conf/wknd/settings/graphql/persistentQueries。 - 选择? 保存 ?以保存新的包定义并关闭对话框。
- 在新创建的包定义中选择? 生成 ?按钮。
生成包后,您可以:
- 下载 包,并在其他环境上重新上传。
- 通过点击? 更多 > 复制 ?来? 复制 ?包。这会将包复制到连接的 AEM 发布环境。