My problem:
我是GraphQL的新手,我正在使用Apollo服务器和客户端开发我的第一个完整堆栈应用程序,这是一个简单的博客 .
在客户端,我在两个不同的页面中使用相同的查询,但具有不同的变量 . 查询是通过ID或slug查询博客文章,具体取决于我使用它的页面 . 所以结果是一样的,只有变量的查询变量 .
当我在一个页面中使用查询时,我认为由于Apollo缓存,查询不会在第二页上运行 . 但事实并非如此 . 查询在第二个中再次运行,当然返回与另一个页面相同的结果 .
为什么Apollo在这种情况下不使用缓存?
Here is the code I use :
在服务器端,我有一个非常基本的查询来从博客中获取文章,可以通过ID或Slug获取:
type Query {
...
article(id: ID, slug: String): Article
...
}
在客户端,如果文章发布,我会通过slug查询文章,或者当它仍然是草稿时,我通过ID查询 .
slug的查询:
<Query
query={article}
variables={{ slug }}
fetchPolicy="cache-and-network"
>
{({ loading, error, data }) => {
return (
<Article
loading={loading}
article={data && data.article}
/>
);
}}
</Query>
除了使用ID的变量param之外,ID的查询是相同的:
<Query
query={article}
variables={{ id }}
>
{({ loading, error, data }) => {
return (
<EditArticle loading={loading} article={data && data.article} />
);
}}
</Query>
如您所见,两者都使用相同的GraphQL endpoints ,结果相同 . 但是没有使用缓存 .
1 回答
Apollo假设您的解析器是纯粹的(它们没有副作用,并且在给定相同输入/参数的情况下,形式地返回相同的结果) . 这已经有很多假设了 . 想象一下,在新闻网站上返回一个随机数或最新评论的解析器 . 给定相同的输入,两者都不会总是返回相同的结果 . 另一方面,Apollo没有做出 - 并且几乎无法做出 - 关于解析器实现的假设 . 虽然在您的脑海中,您的文章解析器的实现是显而易见的(如果
id
存在返回带有该id的文章,如果slug
存在则返回带有该slug的文章)这是从计算机程序要求猜测的很多 .我已经回答了similar question recently . 要防止第二个查询运行,您必须实现cache redirect . 缺点是您必须保持缓存重定向在客户端和服务器上的解析器同步 .