新闻详情

新闻详情

首页 / 资讯中心 / 详情

htmx 中的超媒体 API 与数据 API:为什么超媒体 API 可以拥抱变更而不必版本化

发布时间:2026/9/30 7:02:50来源:尧图网络
htmx 中的超媒体 API 与数据 API:为什么超媒体 API 可以拥抱变更而不必版本化
前端【免费下载链接】htmxhtmx - high power tools for HTML项目地址https://gitcode.com/GitHub_Trending/ht/htmx点击查看免费下载本文深入剖析 htmx 项目核心文档之一《Hypermedia APIs vs. Data APIs》的思想内核超媒体 API通常表现为 HTML over HTTP与数据 API典型如 JSON API拥有截然不同的设计约束与演化策略。你将掌握超媒体 API 的设计方法论、一个真实的表单 轮询表格端点设计案例以及 htmx 源码层面对轮询与表单增强hx-boost的底层实现从而在实际项目中正确区分两类 API 并选择各自的演进方式。什么是超媒体 API什么是数据 API超媒体hypermediaAPI 是指返回超媒体的 API典型形态是通过 HTTP 返回 HTML。它与不返回超媒体的数据 API 形成鲜明对照后者在今天最常见的形态就是无处不在的JSON API。这两类 API 的设计需求截然不同因此在创建时应当采用不同的设计约束与目标超媒体 API天然就是符合 REST 架构风格的因为它正是 Roy Fielding 在博士论文中所描述的那种架构应当由底层超媒体应用的需求驱动可以在没有版本信息的情况下大幅变更因为超媒体利用了自描述消息self-describing messages这一 REST 统一接口特性应当直接呈现给人类用户以最大化系统的灵活性。数据 API不会从彻底的 REST 风格中显著受益至多达到 Richardson 成熟度模型Richardson Maturity Model的第 2 级即可由于消费者对数据的需求任意多样应当同时追求规整性regularity与表现力expressiveness应当进行版本管理并在特定版本内部保持高度稳定应当由代码消费、处理后再视情况呈现给人类。超媒体 API 与数据 API 的根本分野在于前者把人当作最终的交互决策者后者把代码当作直接的消费者。这一分野决定了后续一切设计上的差异——包括对 API 变更churn的容忍度。当今 API 的现状JSON 与 REST 的错位今天的 API 通常被理解为 JSON-over-HTTP。这类 API 几乎总是面向数据的 API而非超媒体 API尽管偶尔也会融入一些超媒体概念通常对最终用户几乎毫无益处。随着行业逐渐认识到将数据 API 硬塞进 REST 模型的问题业界已经出现了一股远离 REST 风格 API的浪潮例如 GraphQL 的兴起。在本文作者看来这是一件好事行业应当在数据 API 领域质疑 REST 式理念转而回望那些在客户端-服务器网络架构上做得更好的早期技术把 REST 归还给它最初被创造出来时所描述的那个网络架构——超媒体 API。设计一个超媒体 API以/contacts为例为展示超媒体 API 与数据 API 在设计上的差异原文引用了一个来自 htmx 社区的Discord真实提问场景我想要一个包含表单和表格的页面。表单负责向表格添加新元素而表格每 30 秒轮询一次以便展示其他用户带来的更新。下面以基础 URL/contacts为例逐步设计这个 UI。第一步渲染表单与联系人表格首先需要一个端点来获取表单和当前的联系人表格它位于/contactsGET /contacts - render the form contacts table对应的 HTML 大致如下div form action/contacts methodpost !-- form for adding contacts -- /form table !-- contacts table -- /table /div到这一步为止这还是标准的 Web 1.0 应用数据 API 与超媒体 API 的需求尚未明显分叉。但值得注意超媒体 API 是自描述的——即使修改创建联系人的 URL也不会破坏整个超媒体应用因为链接关系内嵌在 HTML 之中。第二步添加创建联系人端点接下来支持创建联系人通过向同一 URL 发起 POST 完成并重定向回 GETGET /contacts - render the form contacts table POST /contacts - create the new contact, redirect to GET /contacts第三步为表格加入 30 秒轮询现在进入需要 htmx 的部分偶尔轮询服务器以获取表格更新。为此新增一个只渲染联系人表格的端点/contacts/tableGET /contacts - render the form contacts table POST /contacts - create the new contact, redirect to GET /contacts GET /contacts/table - render the contacts table然后给表格加上轮询触发div form action/contacts methodpost !-- form for adding contacts -- /form table hx-triggerevery 30s hx-get/contacts/table hx-swapouterHTML !-- contacts table -- /table /div在这里超媒体 API 与数据 API 开始明显分叉。这个新端点完全由超媒体需求驱动而非数据模型需求如果应用的超媒体需求发生变化它可以随时消失它的形态可以大幅改动——这一切都是可接受的因为系统是自描述的。第四步让表单也使用 htmx既然已经用 htmx 实现轮询不妨让表单也使用 htmx以获得更好的用户体验div form action/contacts methodpost hx-boosttrue !-- form for adding contacts -- /form table hx-triggerevery 30s hx-get/contacts/table hx-swapouterHTML !-- contacts table -- /table /div如果愿意还可以继续添加诸如输入的服务端校验、动态表单等额外端点。这些端点均由超媒体需求驱动而非任何数据模型考量——我们思考的是应用要达成什么目标而不是数据怎么建模。从源码看轮询与表单增强的底层实现上述案例中用到了 htmx 的轮询触发hx-triggerevery 30s与表单增强hx-boost这些能力在 src/htmx.js 中有完整实现并配有对应测试。every触发器的解析在 src/htmx.js 的parseAndCacheTrigger中every触发器被解析为带pollInterval的触发规格if (trigger every) { const every { trigger: every } consumeUntil(tokens, NOT_WHITESPACE) every.pollInterval parseInterval(consumeUntil(tokens, /[,\[\s]/)) ... triggerSpecs.push(every) }parseInterval负责把30s、5ms这类人类可读的时长换算成毫秒数。测试用例 test/attributes/hx-trigger.js 验证了这一点every 1s解析为pollInterval: 1000every 0s与every 0ms解析为0同时测试还覆盖了带事件过滤条件的写法如every 5ms[foo]确认过滤条件会被解析为eventFilter。轮询的运行机制轮询并非使用setInterval简单重复而是采用链式setTimeout递归调度见 src/htmx.js 的processPollingnodeData.timeout getWindow().setTimeout(function() { if (bodyContains(elt) nodeData.cancelled ! true) { if (!maybeFilterEvent(spec, elt, makeEvent(hx:poll:trigger, { triggerSpec: spec, target: elt }))) { handler(elt) } processPolling(elt, handler, spec) } }, spec.pollInterval)每次触发前都会检查两个条件元素是否仍在文档中bodyContains、是否已被取消轮询cancelled。这种设计意味着当轮询元素因 swap 被移除出 DOM 时轮询会自然停止不会产生悬挂定时器每次轮询都会派发hx:poll:trigger事件可配合事件过滤器做条件轮询若满足过滤条件则跳过本次请求但仍会继续调度下一次轮询。这解释了为什么在超媒体系统中新增/contacts/table这样的页面碎片端点是安全且廉价的——它的生命周期完全由超媒体应用本身管理。hx-boost的表单增强实现在 src/htmx.js 的boostElement中带hx-boosttrue的链接与表单会被转换为 AJAX 请求链接使用get动词与href路径表单则取method默认get与action缺省时回退到当前location.href并通过issueAjaxRequest发起请求。测试 test/attributes/hx-boost.js 覆盖了 POST 表单、GET 表单、formaction/formmethod覆盖、无action属性回退以及methoddialog表单不被增强等场景。对超媒体 API 而言hx-boost的价值在于把标准form/a语义升级为 AJAX 交互却不需要改动任何服务端端点设计——HTML 依旧自描述人类用户依旧通过页面上的控件选择下一步动作。API 变更API Churn超媒体系统为何不怕折腾本篇文章的核心论点可以浓缩为一句话在超媒体系统中API 变更churn是没问题的因为超媒体系统中的消息是自描述的。我们可以大幅改动 API而应用不会崩溃人类用户只需看到新的超媒体HTML然后选择他们想执行的动作即可。人类与计算机相比更擅长决定该做什么对变化的接受度也相当高。这与数据 API 形成鲜明对比。数据 API 一旦修改就会破坏客户端代码因此必须对变更保持高度克制。数据 API 还面临提供更高表现力的压力以便在不修改的情况下满足更多客户端需求。一个值得警惕的旁注浏览器场景下的数据 API原文特别提醒了一种危险情形当数据 API 在浏览器中被消费时情况尤其棘手——因为任何提供给前端开发者的数据 API 表现力同样可以被潜在的攻击者利用他们可以打开控制台直接对 API 发起密集请求。原文提到 Facebook 似乎使用白名单机制来应对这一问题并反问读者你呢这从安全角度进一步佐证了文章主旨在浏览器这个面向人类的运行时里把全部表达能力暴露给代码消费者既增加客户端耦合也扩大攻击面而超媒体 API 把表达面收敛到人通过超媒体选择动作天然限制了这类滥用。结论用不同的设计心态对待两类 API当你在设计一个超媒体 API时应当使用与数据 API 完全不同的设计心态变更churn远不是那么值得担心的问题为良好的超媒体体验提供所需的各种端点应当是你的首要目标端点由应用要达成的交互驱动而非数据模型驱动系统的自描述性让端点可以随应用演化而自由增删改。反过来数据 API 则应当追求规整、版本化、稳定并警惕其在浏览器场景下的安全暴露面。延伸阅读原文位于 www/content/essays/hypermedia-apis-vs-data-apis.md属于 htmx 官方 essays 系列www/content/essays/_index.md《HATEOAS》 用 HTML 而非 JSON 重新解释了 HATEOAS 与自描述消息是理解本文概念基础的最佳续篇轮询触发的完整解析与运行实现见 src/htmx.js配套测试见 test/attributes/hx-trigger.js表单增强hx-boost的实现与测试见 src/htmx.js 与 test/attributes/hx-boost.js。赞分享前端【免费下载链接】htmxhtmx - high power tools for HTML项目地址https://gitcode.com/GitHub_Trending/ht/htmx点击查看免费下载相关推荐REST、超媒体与 HATEOASDjango REST Framework 的超媒体 API 设计指南REST、超媒体与 HATEOASDjango REST Framework 的超媒体 API 设计指南 You keep using that word后端API网关Web框架零训练上手 Chronos10 分钟跑通第一个时间序列零样本预测零训练上手 Chronos10 分钟跑通第一个时间序列零样本预测 你手头有一批时序数据却不想花时间收集样本、调参、训练模型——怎么办Chronos 是亚马人工智能基础模型深度学习使用 API Blueprint 描述超媒体 APIPolls Hypermedia API 实战范本使用 API Blueprint 描述超媒体 APIPolls Hypermedia API 实战范本 API Blueprint 是一套建立在 Markdo文档API设计教程上一篇超长文本问答系统Gemma-2B-10M的检索增强生成实践下一篇7个步骤构建安全可靠的AIGuardrails开源项目的终极治理指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

Windows终端指令指南:盘符切换、C盘文件移到D盘与系统维护 2026/9/30 7:55:04

Windows终端指令指南:盘符切换、C盘文件移到D盘与系统维护

1. 盘符切换背后的逻辑:为什么"cd d:"切不到D盘在终端里敲命令,第一道坎往往不是命令本身多复杂,而是"怎么从C盘跑到D盘去"。搜"电脑终端指令怎么从c盘移到d盘"的人,多半是照着网上的教程敲CD命令然…

阅读更多 →
幻兽帕鲁云服务器开服全教程:选配置、放端口、做备份 2026/9/30 7:55:03

幻兽帕鲁云服务器开服全教程:选配置、放端口、做备份

去年年底幻兽帕鲁刚火起来那阵,我为了拉几个朋友一起玩,顺手在火山引擎上开了一台云服务器折腾私有服。说实话,一开始我以为就是个“买台机器、装个Steam服”的事,结果真上手才发现,从配置选型到端口放行、存档备份&am…

阅读更多 →
域文件服务器共享盘设置:从权限配置到GPO自动映射实战 2026/9/30 7:54:57

域文件服务器共享盘设置:从权限配置到GPO自动映射实战

简介:这份资源面向企业IT运维人员与Windows Server学习者,聚焦在Windows Server 2016环境下搭建域文件服务器共享盘的完整配置思路。内容围绕AD基础结构展开,涵盖组织单位与用户组的创建、文件服务器加入域、共享文件夹与NTFS权限分配&#x…

阅读更多 →
什么是AI技能(Skill)?从原理到实战,手把手教你构建自己的技能包 2026/9/30 7:54:43

什么是AI技能(Skill)?从原理到实战,手把手教你构建自己的技能包

最近不管是在技术社群还是朋友圈,总能看到有人在聊 Skill。一会儿是"Claude 的技能又更新了",一会儿是"这个 Skill 也太好用了吧",甚至还有不少人在分享自己写的 Skill。说实话,我第一次看到这个词的时候也是…

阅读更多 →
Obsidian+Git:打造笔记自动备份与多设备同步的版本管理体系 2026/9/30 7:54:43

Obsidian+Git:打造笔记自动备份与多设备同步的版本管理体系

有一次我熬夜整理完一周的阅读笔记,第二天系统更新后进入桌面发现老文件全部不见了,整个人懵了。好在当时笔记库已经交给Git托管,一条git checkout命令就把半个库救了回来。从那之后,用Obsidian记录、用Git做版本管理,…

阅读更多 →
json-server实战:零代码实现前端接口模拟与联调加速 2026/9/30 7:54:43

json-server实战:零代码实现前端接口模拟与联调加速

第一次听说 json-server 的时候,我正被后端接口进度卡得焦头烂额。需求评审完,前端排期排得密不透风,结果后端同学拍着胸脯说“接口下周给你”,结果下周复下周,眼看联调时间被压缩得只剩两三天,前端组只好在…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉