将 Notion API 用作后端时速度变慢且数据丢失的原因
Notion 数据库的现实局限性
Notion 的界面非常便捷。这就是当独立开发者没有时间分别构建服务器和数据库时选择将 Notion 用作后端的原因。然而,如果在生产环境中维持这种架构,很快就会遇到瓶颈。Notion API 对每个集成令牌(Integration Token)施加了每秒 3 次的请求限制。超出此限制就会引发 429 或 529 错误。
只要数据稍微积聚,问题就会变得严重。单次请求最多只能获取 100 条数据。开发者必须自己实现分页处理,而且由于需要解析嵌套的属性结构,服务器逻辑变得非常复杂。单个页面中属性数据的大小限制为 2.5MB。如果忽视这一限制部署服务,当用户请求涌入时,界面就会卡死或发生数据丢失。
减少 API 调用的缓存与扁平化架构
我们无法每次都干等外部 API 的调用。必须在前方部署缓存层。将静态数据缓存在 Redis 或 Cloudflare KV 中,并通过后台工作线程(Background Worker)定期更新,这样就能在本地处理掉 80% 的总体 API 调用。响应速度可以降至 200 毫秒以下。
在 Python 后端中,还需要一个解析器来将 Notion 复杂的属性进行扁平化处理。Notion 的响应按类型进行了深层嵌套。我们需要编写一个解析器,在遍历字典的同时检查类型字段,将文本合并为字符串,并仅提取关系型数据的 ID 数组。只有经过这个预处理过程,前端开发者才无需编写解析逻辑,直接拿来数据就能使用。
Webhook 同步错误与数据恢复例程
即使在 Notion 中更改了行,如果一收到 Webhook 就立刻调用 API,返回的也会是旧数据。这是因为索引滞后造成的。这也是数据包丢失或数据紊乱的原因。
为了解决这个问题,需要设置定期的后台恢复例程。利用 Notion API 的修改时间戳过滤器将本地缓存与时间戳进行对比。如果发生错误,则通过指数退避(Exponential Backoff)算法等待后重试。必须植入一个仅挑选出最后同步时间点之后更改的记录并进行强制更新的例程,这样才不会破坏数据的一致性。
通过无服务器中间件进行令牌管理与安全防护
在客户端浏览器中直接携带 Notion 密钥发送请求的代码是非常危险的。这会导致令牌直接暴露,还会引发 CORS 问题。这就是为什么必须在中间件中放置一个无服务器中间件代理(Serverless Middleware Proxy)。
客户端将请求发送到无服务器中间件,中间件附加上隐藏在服务器环境变量中的令牌后与 Notion API 进行通信。如果是多租户环境,则必须在中间件中设置一个将应用用户 ID 与 Notion 页面所有者进行映射的反向权限表。只有构建了这种架构,才能防止令牌泄漏事故并安全地隔离数据。