AWS Amplify+NextJS调用AppSync API遇缓存无法清除问题求助
问题
我用AWS Amplify Hosting部署了Next.js前端网站,后端采用Amplify API Category(依赖AWS AppSync与DynamoDB)。已将AppSync API的缓存设置为None,但在getServerSideProps()中调用API.query时,数据仍被缓存且无法清除。Amplify Studio删除记录后,API.query连续数天返回已删除的记录;即使重新部署构建、更新Cache-Control头,问题依旧。无法定位缓存位置,若缓存来自CloudFront,Amplify又隐藏了分发配置无法管理。
相关代码与配置
API调用代码
const clientReviewsQueryResults = await ( API.graphql({ query: listClientReviewModels, authMode: 'API_KEY', variables: { limit: 10, filter: reviewFilter} }) );
Next.js配置文件
/** @type {import('next').NextConfig} */ const nextConfig = { reactStrictMode: true, swcMinify: true, } const withBundleAnalyzer = require("@next/bundle-analyzer")({ enabled: process.env.ANALYZE === "true", }); module.exports = withBundleAnalyzer({ ...nextConfig, async redirects() { return [ { source: '/blog', destination: '/', permanent: true, }, { source: '/contact', destination: '/', permanent: true, }, ] }, })
HTTP响应头
:status: 200 Cache-Control: private, no-cache, no-store, max-age=0, must-revalidate Content-Encoding: gzip Content-Type: text/html; charset=utf-8 Date: Tue, 13 Jun 2023 14:25:53 GMT Server: CloudFront Vary: Accept-Encoding Via: 1.1 9adef5b1c5fc9ca80d6f4f8d19e103a2.cloudfront.net (CloudFront) x-amz-cf-id: N35s80oU9t24Tq-gfsywrlMfahxARl_kJKBK58PBjoU4c8Fytu6Bkw== x-amz-cf-pop: SEA19-C3 x-cache: Miss from cloudfront x-powered-by: Next.js
解决方案
1. 强制禁用Amplify API客户端缓存
Amplify API客户端默认开启本地缓存,即使AppSync端关闭缓存也会生效。调用API.graphql时手动添加cachePolicy参数,强制跳过缓存:
const clientReviewsQueryResults = await ( API.graphql({ query: listClientReviewModels, authMode: 'API_KEY', variables: { limit: 10, filter: reviewFilter}, cachePolicy: 'network-only' // 强制走网络请求,不读取本地缓存 }) );
可选缓存策略包括cache-first(默认)、network-only、cache-and-network、no-cache,这里用network-only彻底绕过客户端缓存。
2. 检查并禁用Next.js数据缓存
getServerSideProps默认不缓存数据,但如果项目配置了next.config.js的缓存选项或第三方缓存插件,可能意外开启缓存:
- 移除任何与
cache相关的自定义配置,比如experimental: { cacheMemoryCount: ... } - 确认未误使用
getStaticProps(当前用的是getServerSideProps,仍需排查)
3. 添加唯一参数破除中间层缓存
如果上述方法无效,在API请求的variables中添加随机值或时间戳,让每次请求签名唯一,避免任何中间层缓存:
const clientReviewsQueryResults = await ( API.graphql({ query: listClientReviewModels, authMode: 'API_KEY', variables: { limit: 10, filter: reviewFilter, cacheBuster: Date.now() // 添加唯一参数,破除缓存 } }) );
注意:需确保AppSync Schema允许该额外参数(可设为可选字段,或用_前缀忽略),不影响业务逻辑。
4. 重新验证AppSync缓存配置
即使已设置为None,仍需再次确认:
- 登录AWS控制台,进入AppSync服务找到目标API
- 进入Settings -> Caching,确认缓存状态为
Disabled - 若之前开启过缓存,手动点击Flush Cache清空残留数据
5. 配置Amplify Hosting边缘缓存规则
Amplify Hosting依赖CloudFront,但可通过amplify.yml控制边缘缓存行为,给API请求路径添加严格缓存控制:
version: 1 frontend: phases: build: commands: - npm run build artifacts: baseDirectory: .next files: - '**/*' cache: paths: - node_modules/**/* headers: - pattern: '/api/*' # 匹配实际API请求路径,按需调整 headers: - key: Cache-Control value: no-cache, no-store, must-revalidate - key: Pragma value: no-cache - key: Expires value: '0'
内容的提问来源于stack exchange,提问作者essedbl

