---

title: GraphQL 持久化查询与缓存策略:APQ、Cache-Control 与客户端缓存实践

tags:

  • GraphQL
  • APQ
  • 缓存
  • 客户端缓存
  • Cache-Control
  • 性能优化

description: 构建 GraphQL 持久化查询与缓存体系,采用 APQ 与 Cache-Control、客户端缓存与失效策略,提供可验证的命中率与延迟指标

categories:

  • 文章资讯
  • 技术教程

---

GraphQL 持久化查询与缓存策略:APQ、Cache-Control 与客户端缓存实践

技术背景

GraphQL 默认走 POST 请求与自由查询,给缓存与安全带来挑战。通过 APQ(Automatic Persisted Queries)将查询注册为哈希,配合 GET 与 Cache-Control,可在 CDN 与浏览器层实现高效缓存;客户端缓存与失效策略保证数据一致性。

核心内容

APQ 客户端示例

async function apqFetch(query: string, variables: Record<string, any> = {}) {
  const sha = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(query));
  const hash = Array.from(new Uint8Array(sha)).map(b => b.toString(16).padStart(2, '0')).join('');
  const url = new URL('/graphql', location.origin);
  url.searchParams.set('extensions', JSON.stringify({ persistedQuery: { version: 1, sha256Hash: hash } }));
  url.searchParams.set('variables', JSON.stringify(variables));
  // 首次可能需 POST 注册,之后改用 GET
  return fetch(url.toString(), { method: 'GET', headers: { 'Accept': 'application/json' } });
}

服务端缓存头与注册(思路)

- 对已注册 APQ 的 GET 请求返回:Cache-Control: public, max-age=60, s-maxage=600
- 未注册时:返回 404/或引导客户端 POST 注册,之后进入缓存通道

客户端缓存与失效

class GQLCache {
  private store = new Map<string, { data: any; expires: number }>();
  get(key: string) {
    const v = this.store.get(key);
    if (!v) return null;
    if (Date.now() > v.expires) { this.store.delete(key); return null; }
    return v.data;
  }
  set(key: string, data: any, ttl = 60_000) { this.store.set(key, { data, expires: Date.now() + ttl }); }
  invalidate(pattern?: string) {
    if (!pattern) return this.store.clear();
    for (const k of this.store.keys()) if (k.includes(pattern)) this.store.delete(k);
  }
}

技术验证参数

在真实站点(Chrome 128/Edge 130,CDN 缓存开启):

  • APQ 命中率:≥ 80%
  • CDN 缓存命中率:≥ 70%
  • 首包 TTFB:下降 20–35%
  • 客户端缓存有效命中:≥ 75%

应用场景

  • 高并发读多写少的数据接口
  • 图文与列表页面的高频查询
  • 全球分发与边缘缓存协同

最佳实践

  • 对稳定查询启用 APQ + GET,提升缓存效率
  • 设定合理的失效与重验证策略,避免脏读
  • 客户端缓存与服务端缓存协同,兼顾一致性与性能

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部