下一个 JS 的 API 缓存

JPM*_*JPM 5 reactjs next.js

我正在使用 Next.js 构建一个应用程序……我们每天有 10 万多个页面和内容更改,因此使用 SSR 和 getServerSideProps。

我们的一些数据来自按请求收费的无头 CMS 提供商。我想将此服务器的 API 响应缓存 24 小时。

解决这个问题的最佳方法是什么?

大多数人使用一个公共图书馆来做到这一点吗?

只是寻找我应该调查的方法的建议(或如何做到这一点的好例子)。

小智 17

我使用了这个 npm 包:https ://www.npmjs.com/package/memory-cache

然后是这样的:

import cacheData from "memory-cache";

async function fetchWithCache(url, options) {
    const value = cacheData.get(url);
    if (value) {
        return value;
    } else {
        const hours = 24;
        const res = await fetch(url, options);
        const data = await res.json();
        cacheData.put(url, data, hours * 1000 * 60 * 60);
        return data;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,如果您想使用缓存获取某些内容,只需调用此函数即可。或者它可以用作请求中的中间件。它检查数据是否已经在缓存中并返回它,或者如果没有 - 它将数据放入键下的缓存中。密钥可以是任何东西,例如我正在使用 url。

  • 不保证这在生产中有效。Vercel API 使用无服务器无状态函数并具有最长执行持续时间。我做了一些测试,缓存不会在配置的时间内持续存在。 (2认同)

小智 16

除了托拜厄斯·林斯的回答之外:

至少如果在 Vercel 上部署,您可以在 getStaticProps、getServerSideProps、API 路由等中使用设置的 Cache-Control 标头来缓存 Vercel 边缘网络上的响应。该解决方案不需要任何额外的依赖项和非常少的代码。

api 路由示例 - 来源 Vercel

// pages/api/user.js

export default function handler(req, res) {
  res.setHeader('Cache-Control', 's-maxage=86400');
  res.status(200).json({ name: 'John Doe' });
}
Run Code Online (Sandbox Code Playgroud)

getServerSideProps 中的示例 - 来源 NextJS

// This value is considered fresh for ten seconds (s-maxage=10).
// If a request is repeated within the next 10 seconds, the previously
// cached value will still be fresh. If the request is repeated before 59 seconds,
// the cached value will be stale but still render (stale-while-revalidate=59).
//
// In the background, a revalidation request will be made to populate the cache
// with a fresh value. If you refresh the page, you will see the new value.
export async function getServerSideProps({ req, res }) {
  res.setHeader(
    'Cache-Control',
    'public, s-maxage=10, stale-while-revalidate=59'
  )

  return {
    props: {},
  }
}
Run Code Online (Sandbox Code Playgroud)

我相信你会想使用:

res.setHeader('Cache-Control', 's-maxage=1440000')
Run Code Online (Sandbox Code Playgroud)

以下是 Vercel 上缓存的一些其他有用链接:

对于您的具体情况,您可能还需要研究将 getStaticPaths 与 getStaticProps 一起使用。您可以使用fallback: truegetStaticPaths 仅在访问页面时构建页面(您仍然可以在初始构建时构建帖子热门页面)。

我知道这是一篇旧文章,但对于其他人(至少是在 Vercel 上部署的人)来说,这些解决方案应该对 getStaticProps 中的 revalidate 没有帮助的地方有所帮助。

  • 我不确定这是否回答了问题。我可能会错,但是OP想要缓存来自next.js下游系统的响应,而这个答案缓存next.js本身的响应。想象一下,为了构建页面,您需要从 CMS 获取促销横幅。您不希望 10000 个用户获取相同的横幅,您希望横幅保留在 next.js 服务器上并从磁盘中提取,仅偶尔更新。 (8认同)

Tob*_*ins 7

您可以将getStaticPropsNext.js 用于 SSG

它们目前有一个revalidate您可以返回的属性,该属性定义了重新获取内容的频率。

看看这里:https : //nextjs.org/blog/next-9-5#stable-incremental-static-regeneration

  • `revalidate` 已稳定发布 https://nextjs.org/blog/next-9-5#stable-incremental-static-regenesis (4认同)