我的问题:
我对GraphQL还是很陌生,我正在使用Apollo服务器和客户端(这是一个简单的博客)开发我的第一个全栈应用程序。
在客户端,我在两个不同的页面中使用相同的查询,但是具有不同的变量。查询是根据ID或Slug查询博客文章的,具体取决于我使用的页面。因此结果是相同的,只是查询变量发生了变化。
当我在一页中使用查询时,由于Apollo缓存,我认为查询不会在第二页上运行。但这不是正在发生的事情。该查询将在第二个查询中再次运行,并且当然会返回与其他页面相同的结果。
为什么在这种情况下Apollo为什么不使用缓存?
这是我使用的代码:
在服务器端,我有一个非常基本的查询来从博客中获取文章,可以通过ID或Slug进行获取:
type Query {
...
article(id: ID, slug: String): Article
...
}
在客户端,如果文章已发布,我将按Slug来查询文章,如果仍然是草稿,则将按ID查询。
由子弹查询:
<Query
query={article}
variables={{ slug }}
fetchPolicy="cache-and-network"
>
{({ loading, error, data }) => {
return (
<Article
loading={loading}
article={data && data.article}
/>
);
}}
</Query>
ID的查询是相同的,除了使用ID的变量param:
<Query
query={article}
variables={{ id }}
>
{({ loading, error, data }) => {
return (
<EditArticle loading={loading} article={data && data.article} />
);
}}
</Query>
如您所见,这两个都使用相同的GraphQL端点,结果是相同的。但是不使用缓存。
[Apollo假定您的解析器是纯函数(它们没有副作用,并且在输入/参数相同的情况下,大多数返回相同的结果)。这已经是很多假设。想象一个解析器在新闻网站上返回一个随机数或最新评论。给定相同的输入,两者都不会总是返回相同的结果。另一方面,Apollo不会(几乎无法做出)关于解析器实施的假设。虽然在您的头脑中,您的文章解析器的实现是显而易见的(如果id
存在,则返回具有该ID的文章,如果slug
存在,则返回具有该子句的文章),这是很多计算机程序要问的问题。
我已经回答了similar question recently。为了防止第二个查询运行,您必须实现一个cache redirect。缺点是您必须使客户端上的缓存重定向与服务器上的解析器保持同步。