工程2026-03-276 分钟

一个可以拔除而不会让网站崩溃的内容后端

无头 CMS 的锁定是一种你需要永远支付的慢性税。我们构建了一道接缝:今天用文件,明天用无头,而在数据库宕机的那天还有文件兜底。

过去选择一个 CMS 就意味着与它结婚。您的模板学会了它的怪癖,您的内容模型迁就了它的 schema,三年之后所谓“切换一下”就意味着一次重建。我们设计内容层的方式,让这个决定始终可逆。

所有读取内容的逻辑都经过一个单一的、与提供方无关的适配器,由一个环境变量切换:CMS_PROVIDER 取值要么是 file,要么是 headless。在 file 模式下,内容存放在受版本管理的源代码中——可 diff、可评审、随代码一同部署。在 headless 模式下,同一个适配器与一个远程源通信,并缓存一份已发布的快照。它之上的页面不知道也不在意哪一个处于激活状态;它们调用同一个接口,得到同一种形状的返回。

我们最引以为傲的部分是失败行为。适配器在每次读取时都会报告自己的来源——live-remote、snapshot-cache 或 file-fallback——而当远程源不可达时,它会降级回退,而不是把页面留白。数据库宕机变成了一次降级读取,而非一次中断。访客看到的是内容;我们看到的是一条被记录下来的回退原因。这就是一起事故与一桩无事之间的区别。

我们拒绝这样做:把某个供应商的 API 调用硬编码进页面组件,让内容建模被某个 CMS 的管理界面所支配,或者构建一个一旦其后端打嗝就立刻返回错误的站点。我们也不假装这道接缝是免费的——一层抽象在间接性上是有成本的。我们明知故付地承担它,因为另一种选择是日后连本带利地偿还一笔迁移税。

原则是:依赖一道接缝,而非一个供应商。如果您的内容层能用一个环境变量就被替换,并能在自己的后端陷入黑暗时依然存活,那么内容就归您所有。如果替换它意味着一次重写,那么供应商就拥有了您。我们宁愿现在吸收一点间接性,也不愿把对我们路线图的否决权交到别人手里。

联系我们