持久 GraphQL 查询 persisted-graphql-queries
持久查询是创建并存储在 Adobe 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 命令行工具使给定的查询持久:
-
使用 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级别编码两次。
要避免出现这种情况,请执行以下操作:-
启用
DispatcherNoCanonURL
在Dispatcher上。
这将指示Dispatcher将原始URL转发到AEM,以防止编码重复。
但是,此设置当前仅在vhost
级别,因此,如果您已有Dispatcher配置来重写URL(例如,在使用缩短的URL时),您可能需要单独的vhost
用于持久查询URL。 -
发送
/
或\
字符未编码。
在调用持久查询URL时,请确保所有/
或\
在持久查询变量的值中,字符保持未编码状态。note note NOTE 仅当满足以下条件,才建议使用此选项 DispatcherNoCanonURL
无法实施解决方案,因为没有任何原因。
-
-
CACHE_GRAPHQL_PERSISTED_QUERIES
时间
CACHE_GRAPHQL_PERSISTED_QUERIES
为Dispatcher启用,然后;
不能在变量的值中使用字符。
正在缓存您的持久查询 caching-persisted-queries
建议使用持久查询,因为可在 Dispatcher 和内容交付网络 (CDN) 层缓存此类查询,最终提高发出请求的客户端应用程序的性能。
默认情况下,AEM 将根据生存时间 (TTL) 定义使缓存失效。可通过以下参数定义这些 TTL。可通过多种方式访问这些参数,其名称因所使用的机制而异:
max-age
cache-control : max-age
cacheControlMaxAge
graphqlCacheControl
s-maxage
surrogate-control : max-age
surrogateControlMaxAge
graphqlSurrogateControl
stale-while-revalidate
surrogate-control : stale-while-revalidate
surrogateControlStaleWhileRevalidate
graphqlStaleWhileRevalidate
stale-if-error
surrogate-control : stale-if-error
surrogateControlStaleIfError
graphqlStaleIfError
创作实例 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。
PUT(创建)方法的示例:
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} }'
POST(更新)方法的示例:
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 环境变量以定义所需的值:
graphqlStaleIfError
graphqlSurrogateControl
使用 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
读 graphqlCacheControl
surrogateControlMaxAge
读 graphqlSurrogateControl
surrogateControlStaleWhileRevalidate
读 graphqlStaleWhileRevalidate
surrogateControlStaleIfError
读 graphqlStaleIfError
-
如果不可用,OSGi 配置将使用发布实例的默认值。
配置查询响应代码 configuring-query-response-code
默认情况下,无论实际结果如何,PersistedQueryServlet
在执行查询时都会发送200
响应。
当持久化查询中出现错误时,您可以为 持久化查询服务配置 配置 OSGi 设置,以控制 /execute.json/persisted-query
端点返回的状态代码。
字段 Respond with application/graphql-response+json
(responseContentTypeGraphQLResponseJson
) 可以根据需要定义:
-
false
(默认值):
持久化查询成功与否无关紧要。/execute.json/persisted-query
返回状态码200
,返回的Content-Type
标题为application/json
。 -
true
:
当运行持久化查询时出现任何形式的错误时,端点将返回400
或500
(视情况而定)。此外,返回的Content-Type
是application/graphql-response+json
。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 JavaScript、Java 或 NodeJS。Headless 客户端 SDK 将自动在请求中正确编码任何查询变量。
正在将持久查询转移到生产环境 transfer-persisted-query-production
应始终在 AEM 创作服务上创建持久查询,然后将其发布(复制)到 AEM 发布服务。通常,持久查询会在本地或开发环境等较低环境中创建和测试。然后,有必要将持久查询提升到更高级别的环境,最终在生产 AEM 发布环境中提供,以供客户端应用程序使用。
持久查询包
可以将持久查询构建在 AEM 程序包中。然后,可以在不同的环境中下载和安装 AEM 包。AEM 包也可以从 AEM 创作环境复制到 AEM 发布环境。
要创建包:
- 导航到 工具 > 部署 > 包。
- 点击 创建包 创建一个新包。这将打开一个用于定义资源包的对话框。
- 在包定义对话框中,在 常规 下输入 名称,如“wknd-persistent-queries”。
- 输入版本号,如“1.0”。
- 在 过滤器 下添加新的 过滤器。使用路径查找器选择
persistentQueries
文件夹。例如,对于wknd
配置,完整路径为/conf/wknd/settings/graphql/persistentQueries
。 - 选择 保存 以保存新的包定义并关闭对话框。
- 选择 生成 按钮创建包定义。
生成包后,您可以:
- 下载 包,并在其他环境上重新上传。
- 通过点击 更多 > 复制 来 复制 包。这会将包复制到连接的 AEM 发布环境。