API 在一个星期二上线了。我不知道谁会使用它。
我正在构建 NewTqnia,一个提供英语和阿拉伯语双语内容的科技出版物,需求不断扩大。网站、RSS、JSON API、可嵌入小部件、浏览器新标签页、结构化时间线——每一个都需要以不同方式交付相同的内容。
这引出了一个我至今仍没有明确答案的问题:
如何在不构建六个互不相连的产品的情况下,支持六种内容分发渠道?
这不是一个成功故事。它是一系列权衡,有些有效,有些值得商榷,还有一些我正在积极撤销。
API:有意保持精简
首个公开版本的 Daily Digest API 几乎什么都没做。
curl "https://newtqnia.com/v1/news/today?locale=en&limit=5"
Enter fullscreen mode Exit fullscreen mode
就是这样。today、latest,两个查询参数,无需 API 密钥。每分钟 60 次请求,支持 ETag,合理的 Cache-Control。
我本可以在第一天就发布分类、标签、搜索、推荐和分析端点。但一个拥有不稳定契约的大型 API,只不过是一个碰巧有公开文档的私有 API。我想要的正好相反:一个小型接口,即使有人真的基于它构建,也不会让我难堪。
尴尬之处在于:开发者无法请求他们不知道可能存在的端点。所以“等待需求”是安全的策略,但可能不是正确的策略。我仍在寻找“谨慎地精简”与“无用地精简”之间的界限。
小部件问题:隔离的代价
有些人只是想在自己的网站上展示标题,而不想编写 HTTP 客户端。于是我构建了一个脚本:
<script
async
src="https://newtqnia.com/news-widget.js"
data-count="5"
data-locale="en"
data-layout="cards"
data-orientation="horizontal"
data-theme="auto"
data-accent="#03c0f9"
data-order="latest"
data-show-image="true"
data-show-summary="true">
</script>
Enter fullscreen mode Exit fullscreen mode
小部件生成器会生成这段代码并显示实时预览。
这里有一个没人警告过我的问题:每一种隔离策略都会将复杂性转移到别处。
- Iframe? 样式隔离强,但响应式尺寸会变成与宿主页面的协商。
- Shadow DOM? 防止 CSS 泄漏,但主题和无障碍遍历会变得奇怪。
-
带作用域 CSS 的普通脚本? 对嵌入者来说熟悉,但宿主页面的一条
!important规则就能让你的布局崩溃。
我目前选择了简单的脚本和 data-* 属性。我不认为这是长期答案。如果你发布过可嵌入小部件,我真诚地想知道:你是否后悔一开始没有使用 Web Components?
时间线不是文章
新闻文章描述一个时刻。时间线必须解释多年间这些时刻如何关联。
我们发布关于生成式 AI 的演进和互联网的历史等主题的时间线。在内部,这些不是长文章,而是带有以下字段的事件集合:
- 精确或近似日期
- 事件类型和重要性级别
- 主要和次要来源
- 相关链接
- 事件特定媒体
- 双语标题和替代文本
- 署名和许可
这使得内容可复用,但也引入了代码无法解决的编辑问题。当两个可靠来源对日期存在分歧时该怎么办?如何标记时间线为不完整而不损害其可信度?如何表示一个可信但次要的来源?
我对公开格式也不确定。自定义 JSON 易于设计。JSON-LD 或现有事件词汇表更难,但互操作性更强。如果你从 API 消费时间线数据,你更倾向于哪种?
双语支持始于数据模型
阿拉伯语不是“换成不同单词的英语”。它需要 RTL 布局、不同的排版、本地化日期,以及不一定与英语端镜像的界面决策。
对于结构化内容,最简单的模型是显式的双语字段:
{
"title_en": "The Transformer rewrites the architecture of language AI",
"title_ar": "بنية المحولات تعيد صياغة هندسة الذكاء الاصطناعي اللغوي"
}
Enter fullscreen mode Exit fullscreen mode
当你只有两种语言时,这很容易查询和验证。当有五到十种语言时,它会变得丑陋。规范化的翻译表扩展性更好,但会增加我目前不需要的连接、回退逻辑和发布状态复杂性。
我目前的规则是:在添加第三种语言之前重新考虑模型,而不是之前。过早规范化仍然是过早优化。
媒体意外成为一个子系统
当时间线开始使用事件特定图像时,仅存储单个 URL 已不够用。一个有用的媒体记录现在需要:
- 稳定的内部 ID
- 处理状态和响应式变体
- 尺寸和文件类型
- 双语替代文本和标题
- 原始来源、署名和许可
- 与时间线或单个事件的关联关系
图像被处理成多种尺寸和格式。事件引用内部资源,而不是外部 URL。这将无障碍元数据附加到它所描述的内容上,并避免将发布页面与第三方主机的正常运行时间绑定。
我无法自动化的部分:替代文本是否真正好。验证仅检查是否存在,不检查是否有用。
分发创建了署名边界
你让内容越便携,对其使用方式的控制就越少。
仅返回标题和 URL,API 几乎没用。返回完整文章,你就是在邀请未署名的再版。摘要是折中方案,但即使是摘要也会被聚合到无面目的信息流中。
目前 API 要求消费者保留文章 URL 并显示可见的署名。这是社会契约,而不是技术契约。我研究过签名内容、更严格的条款、计量访问和 API 密钥。每一种都会提高合法实验的成本。
如果你设计过公开内容 API,你是如何决定要给出多少内容的?
我会做不同的选择
- 更早开始使用时间线数据模型。 先将时间线视为文章意味着我本可避免的一次迁移。
- 更严格地质疑嵌入策略。 一个脚本标签感觉是简单路径,直到你在一个不控制的站点上调试 CSS 特异性。
- 记录 API 的理念,而不仅仅是它的端点。 开发者需要在决定是否在其上构建之前了解它为什么小。
我卡住的问题
如果你要审查这个系统,我希望听到你对以下问题的看法:
- 范围蔓延: 一个小型 REST API 在什么时候需要分类、标签或搜索?
- 推送 vs. 拉取: 新故事的 webhook 是否有用,还是 RSS 已经解决了这个问题?
-
嵌入接口:
data-*脚本在 2026 年仍然是好的集成格式吗? - Web Components: 它们真的解决了小部件隔离问题,还是只是转移了问题?
- 时间线格式: 你会如何在公开 API 中表示有来源的历史事件?
- 多语言模型: 支持未来扩展的最不复杂的模型是什么?
- 内容边界: 公开新闻 API 应该返回多少文章内容?
- 版本控制: 在 API 增长之前,我应该修复哪些缓存或契约错误?
你可以通过开发者页面、小部件生成器和实时的时间线集合来查看当前实现。
如果这个系统中的某一部分值得被简化、替换或完全避免,那会是哪一部分?
Enter fullscreen mode Exit fullscreen mode
0 Comments
Log in to join the conversation.No comments yet. Be the first to share your thoughts.