
AI帮我造博客(四):后端选型——内容从哪里来?

TL;DR
内容管理是博客的核心。我是个既要又要的程序员,想要 Markdown 的写作自由,又想要 CMS 的管理便利。在考察了 Strapi、Payload 和 Directus 之后,我最终选了 Strapi。
它社区最大,遇到坑最容易搜到答案。对于在这个项目上不想造后端轮子的我来说,这就是最优解。
内容的家在哪里?
架构设计(前后端分离)搞定之后,摆在面前的是一个很具体的问题:我写的文章,到底该存在哪?
最简单的方案是 Git + Markdown。像 Hexo 或 Hugo 那样,把文章当成 .md 文件放在仓库里,编译时读取。这是程序员最舒心的方案,版本控制、本地编辑器、离线写作,一切尽在掌握。
但我想要的不只是一个静态博客,而是一个内容系统。
想想用纯文件管理几百篇文章有多痛苦:
- 改标签:想把 "AI" 这个标签改成 "Artificial Intelligence",我得写脚本遍历几十个文件去替换文本。
- 搞推荐:想在文章底部加一个"相关阅读",只靠文件系统几乎没法做,除非每次编译都把所有文章读一遍来算相关性。
- 做互动:文件是静态的,存不了读者的评论、点赞。
所以我需要一个 Headless CMS(无头内容管理系统)。
不理解"无头"是什么意思也没关系,你可以把它想象成一个只有后厨的餐厅:它只管把菜(内容数据)做好切好,通过窗口(API)递出来。至于这盘菜是端到豪华包间(Web端)、打包带走(App端)还是喂给机器人(AI训练),它完全不管。它只负责存数据、提供接口。
三个候选:Strapi、Payload、Directus
在 AI 的辅助调研下,我把范围锁定在三个主流选手身上。挑选它们的过程,有点像选车。
1. Payload CMS:程序员的梦中情车
Payload 是最让我纠结的那个,也是当下 Next.js 生态里最火的新星。
它的核心哲学是 Code-First(代码即结构)。
传统 CMS 里,你通常要登录后台,点"创建模型",输入"文章",加"标题"字段,一顿鼠标点下来,系统才把数据结构存进数据库。
Payload 不一样,你是在写代码。定义一个 Article.ts 配置文件,写上 fields: [{ name: 'title', type: 'text' }],保存,后台界面自动生成,数据库表也建好了。相当于用代码"画"出了后台。
为什么它这么招我喜欢?
- 版本控制友好:所有数据结构的变化都在代码里,Git 提交记录清清楚楚。
- 开发体验好:它本身就是 TypeScript(一种自带类型"拼写检查"的升级版 JavaScript)写的,你在后端定义的字段,前端调用时自动就有类型提示。再也不用纠结"我那个字段到底叫
img还是image"。 - 灵活:它不像一个外挂系统,更像一个你可以随心定制的 npm 包。
拿车打比方,它像一辆自己组装的高性能赛车。没有多余的内饰,但引擎、悬挂、变速箱的每个参数都由你控制,开起来人车合一。
2. Directus:极致性能的瑞士军刀
Directus 走的是另一条路:Database Mirroring(数据库镜像)。
大多数 CMS 会在数据库之上封一层厚厚的逻辑,把你和数据库隔开。Directus 不这么干,它更像给数据库套了层皮肤。你给它一个现有的 Postgres 或 MySQL 数据库,它瞬间分析你的表结构,然后立刻生成一套漂亮的 API 和一个功能完备的后台。你不用迁移数据,也不用为了迁就 CMS 去改表结构。
它的杀手锏:
- 即时 API:连上一张表,API 马上就通。
- 无依赖:哪天不想用了,直接删掉,数据库干干净净,不留任何 CMS 的垃圾字段。
- 性能好:中间层极薄,加上 Node.js 的底层优化,响应通常是毫秒级。
它像一把精密的瑞士军刀,冷峻、高效、多功能。它不教你怎么管理内容,只给你最锋利的工具,还允许你直接操作最底层的素材。
3. Strapi:略显臃肿的老大哥
最后是 Strapi,市场占有率第一的老大哥。
说实话,它的技术架构放今天看有点"油腻"。启动慢,空跑内存就要占几百兆;后台功能全,但加载起来总有一种钝感。而且它的版本升级(尤其 v4 到 v5)经常因为破坏性变更让开发者叫苦连天。
但它赢在"平庸的全面"。它不要求你懂 TypeScript(Payload 的门槛),也不要求你懂数据库设计(Directus 的门槛)。它提供一个可视化的 Content-Type Builder,像搭积木一样,拖个文本框、拖个图片上传区,后台就搭好了。这是最接近传统 WordPress 使用体验的 Headless CMS。
它像一辆传统燃油 SUV。费油、起步肉、车机也不智能,但皮实、空间大、配件便宜,开到哪个修车店师傅都会修。对不想折腾的人来说,这就叫靠谱。
横向对比表
| 维度 | Strapi | Payload | Directus |
|---|---|---|---|
| 一句话定位 | 社区最强、生态最丰富 | TypeScript 开发者首选 | 数据库包装器、极致性能 |
| 开发模式 | GUI (界面拖拽) | Code-first (写代码) | GUI (直接映射数据库) |
| GitHub Stars | ~70k | ~40k | ~34k |
| 管理界面 | React | React | Vue.js |
| API 响应 | 120-150 ms | 80-100 ms | 33 ms |
| 推荐配置 | 4核/8GB | 2核/4GB | 1核/1GB |
| TS 支持 | ⭐⭐⭐ (能用) | ⭐⭐⭐⭐⭐ (完美) | ⭐⭐⭐⭐ (不错) |
| 学习曲线 | 简单 | 陡峭 (需熟练 TS) | 中等 (需懂 SQL) |
还有谁?其他值得一看的选手
除了这三位主角,市面上还有几个老面孔,简单说下我为什么没选:
WordPress (Headless 模式)
老牌王者。它也能当 Headless 用,但内核依然是 PHP。我想全栈用 JavaScript,不想在服务器上再装个 PHP 环境,也不想维护那个庞大的插件库。
Ghost
专注博客的优雅选手。界面极美,写作体验极佳,但它太"博客"了。如果我只想写写文章,选它准没错。可我想做一个更通用的内容系统,Ghost 的扩展性稍差点意思。
Sanity / Contentful
SaaS 领域的贵族。它们不提供自托管版本(或者很难搞),数据存别人家。对我这种想把一切抓在手里的数据控制狂来说,不能自托管就是一票否决。
为什么我不争气地选了 Strapi?
这其实是我内心最大的挣扎。
作为一个有追求的工程师,我本能地更喜欢 Payload。它的 Code-first 模式太优雅了,所有配置都在代码里,能进 Git 版本控制。而 Strapi 里你在后台拖拽生成的 Schema(数据模型)是以 JSON 文件存在的,虽然也能进 Git,但总感觉在操作一个黑盒。再加上 Payload 原生支持 TypeScript,对我吸引力巨大。
但我最终还是选了 Strapi,理由很现实,甚至有点俗:
1. 出了 Bug 能搜到答案
Strapi 的 GitHub Stars 比另外两家加起来还多。这意味着我遇到的任何报错,Google 一下,StackOverflow 上大概率有人问过。Payload 当时(2025 年初)社区还比较嫩,遇到问题经常得去 Discord 翻记录或者读源码。对一个不想在后端耗太多精力的人来说,Strapi 这种"满大街都是修车店"的安全感太重要了。
2. 可视化建模的傻瓜优势
Payload 的代码定义确实帅,但 Strapi 的 Content-Type Builder(可视化拖拽建表)对新手真的太友好了。有时候我只是想加个"置顶"字段,或者给文章加个"标签"关系,Strapi 里点两下鼠标就完了,不用切代码、不用重新编译、不用管 TS 类型定义。这种所见即所得,在项目初期极大地降低了心智负担。
3. 插件如海
Strapi 拥有最庞大的插件市场。SEO 插件、Sitemap 生成、图片格式转换,基本一搜都有。我想做 SEO 优化,装个官方 SEO 插件,填填空就好。同样的事在 Payload 里,当时我可能得自己写 Hook 来注入 meta 标签。对想快速上线的我来说,能不重复造轮子就不造。
如果你是初级个人开发者,或者团队里有非技术人员要管理内容,Strapi 到今天依然是我最推荐的大众选择。它不够完美,但足够稳。
这一路踩过的坑
既然是真实记录,就不能只报喜不报忧。虽然选了 Strapi,但这几个坑是实实在在的。
1. 资源占用是硬伤
Node.js 应用的内存管理一直是个谜。Strapi 跑起来后,小内存服务器(比如 1 核 2G)经常因为内存不足崩溃(OOM,Out Of Memory)。后来我不得不在服务器上加了 Swap(虚拟内存,把一部分硬盘当内存用)才稳住它。
2. 到底是 CMS 还是数据库?
Strapi 默认把所有数据都存数据库,包括我精心排版的文章内容。这带来一种分裂感:我在本地写 Markdown 很爽,复制进 Strapi 的富文本编辑器,体验就降级了。这也导致我后来做了一个很复杂的同步脚本(这是后话),强行让本地 Markdown 和远程 Strapi 共存,用 Strapi 做数据管理,用本地文件做写作源。这算是对 Strapi 编辑体验不佳的一种妥协。
3. 富文本的烦恼
Strapi 的富文本字段输出的是 Markdown,但前端渲染时又是另一回事。图片怎么处理?站内链接怎么跳转?代码高亮怎么做?这些都得在前端用 react-markdown 之类的库再解析一遍。并不是"存进去什么样,拿出来就什么样"。
一点剧透
这篇文章记录的是项目初期的决策过程。软件工程没有银弹,只有当下的取舍。几个月后,随着我对内容控制力的要求进一步提升(用 Python 重写了整套同步系统),Strapi 那个引以为傲的可视化后台,对我来说反倒有些累赘了。
但这不妨碍 Strapi 在现阶段是我的最佳选择。它像新手村里那把最顺手的铁剑,虽然以后我很可能换上更轻盈的光剑(Payload),但没有这把铁剑,我可能连村口都出不去。
如果让我现在重新选,在完全具备驾驭复杂系统的能力之后,我可能会转向 Payload。但这不正是成长的乐趣吗?
总结
后端选型,本质上是在选数据流动的起点。
我放弃了极致的性能(Directus)和极致的开发体验(Payload),选了一个最稳妥、资料最多、虽然有点笨重但足够成熟的方案,Strapi。
因为它让我的数据有了家,也让我能腾出手去处理更重要的部分:这个博客到底长什么样?
这就是下一篇的主题,前端选型,为什么是 Next.js?