目录
s 1. Introduction:
2. What is On-demand validation and how it works:
3. Setup:
4. A Catch
5. Conclusion
6. References
介绍:
创建博客页面或产品登录页面时,我们希望它们是静态页面。因为,它不太可能在它们上具有动态内容或复杂的交互。在组织中,有开发人员参与发布每个营销页面或博客页面是不可扩展的。因此,将发布流程从开发人员到管理内容的各个团队是合乎逻辑的。
这导致内容渲染和内容发布过程的分离。当团队发布内容(在某个工具中)时,理想的流程将是在不用任何开发人员参与的情况下反映所需的目标(网站)。
在此博客中,我们将讨论如何使用无头CMS,Next JS和Vercel的基础架构实现上述功能。
什么是按需验证及其运作方式:
当将静态网站部署到Vercel时,该页面实际上是从Vercel的CDN提供的,也称为“边缘网络”。边缘网络靠近消费者区域以迅速服务。当部署发生时,CDN的缓存将无效。因此,当请求提交CDN时,页面请求将从Vercel的服务器中提供,新页面将存储在CDN的缓存中。
可以有一个用例,其中一个页面可能必须在定期时间间隔中刷新其内容。为了支持此增量静态再生提供。
但是,也可以有某些用例,其中页面不必在间隔中刷新其内容,但是,每当添加,删除或更新的新数据时,它应该反映出新的/更新的内容CMS。 按需验证将有助于我们解决此问题。
在CMS中的内容上执行操作时,我们将利用下一个JS的revalidate
API,以使边缘CDN中的缓存无效,而cdn中的cache in-turns in-turns刷新了各个页面。基本上,它正在模仿特定页面的部署。
设置:
我们将在此博客文章中使用Strapi和Next JS(页面路由器)来创建博客列表页面。
使用页面路由器配置创建下一个应用程序
npx create-next-app@latest
创建一个strapi项目yarn create strapi-app my-blogs-strapi
在进行下一个JS项目之前,让我们结束我们的Strapi部分。
在Strapi中,我们将创建一个内容类型,代表博客文章的外观。一旦定义了内容类型,作者可以使用Content Manager发布与内容类型相对应的内容。
对于此博客文章的范围,让我们创建一个名为blog
的内容类型,该内容具有blogTitle
和blogDescription
字段。
创建内容类型后,我们将创建用于CRUD(创建,读取,更新和删除)操作的Webhook。
创建一个webhook,这是在内容类型上执行任何操作时,要由Strapi提出发布请求的端点。我们将使用下一个JS API路由来创建端点。
让我们在API文件夹中创建一个名为revalidate.js
的文件。重新验证的道路将是/api/revalidate
。带有请求正文的帖子请求将由Strapi向此端点。
strapi关联的请求主体具有三个主要属性,
- 条目
- 模型
- 事件
event
:描述是否创建,更新,发布或未发布内容。
model
:代表一个内容类型。在这种情况下,是blog
。
entry
:表示内容管理器执行操作的条目。
示例有效载荷可以从CodeBlocks引用。
{
event: 'entry.create',
createdAt: '2023-06-11T11:42:51.225Z',
model: 'blog',
uid: 'api::blog.blog',
entry: {
id: 1,
blogTitle: 'Blog 1',
blogDescription: 'Blog description 1',
createdAt: '2023-06-11T11:42:51.220Z',
updatedAt: '2023-06-11T11:42:51.220Z',
publishedAt: null
}
}
{
event: 'entry.update',
createdAt: '2023-06-11T11:42:54.458Z',
model: 'blog',
uid: 'api::blog.blog',
entry: {
id: 1,
blogTitle: 'Blog 1',
blogDescription: 'Blog description 1',
createdAt: '2023-06-11T11:42:51.220Z',
updatedAt: '2023-06-11T11:42:54.456Z',
publishedAt: '2023-06-11T11:42:54.455Z'
}
}
{
event: 'entry.publish',
createdAt: '2023-06-11T11:42:54.458Z',
model: 'blog',
entry: {
id: 1,
blogTitle: 'Blog 1',
blogDescription: 'Blog description 1',
createdAt: '2023-06-11T11:42:51.220Z',
updatedAt: '2023-06-11T11:42:54.456Z',
publishedAt: '2023-06-11T11:42:54.455Z'
}
}
但是,我们对属性事件和模型感兴趣。因为,事件告诉我们内容类型发生了什么,并描述了内容类型的更新。尽管这些属性解决了此博客的范围,但如果我们必须重新验证特定页面,例如博客详细信息页面,entry
属性将很有用。没有模型,可能不可能知道要重新验证哪个页面。例如,如果模型是博客,并且可以使用博客列表页面,那么每当在博客内容类型上执行操作时,我们都必须重新验证博客列表页面。
revalidate.js
的示例代码
const modelToPageMap = {
blog: "/blogs",
};
export default async function handler(req, res) {
const requestMethod = req.method;
if (requestMethod === "POST") {
const requestBody = req.body;
const model = requestBody.model;
await res.revalidate(modelToPageMap[model]);
return res.json({ revalidated: true });
} else {
return res.status(405).json({
text: "Method not supported",
});
}
}
捕获
我们正在通过重新验证API的途径。有可能不存在路径的机会。例如,当我们创建一个新博客时,API将使用 /blog /[new-blog-url]重新验证。但是,此路径不存在。因此,重新验证将失败。为了处理这种情况,一个好的做法是配对Getstatic Paths和GetStaticProps。如果返回后返回true
,则没有返回404,而是在GetStaticProps获取特定页面的数据时可以显示加载程序屏幕。如果数据不可用,我们可以重定向到404或以可自定义的方式处理。一旦构建了新页面,就可以在更新或未发布操作时执行重新验证。
结论
按需重新验证有助于我们优化页面增量静态再生时执行的重新验证数量。大多数成熟的CMS都将具有Webhook来实现此功能。出于此博客的目的,Localhost给出了Webhook的终点。对于准备生产,它需要用实际的HTTPS端点代替。