摘要: 如果你将API拆分为数据和应用API,如此处所倡导的,你应该考虑将应用API从JSON改为超媒体(HTML)并使用像htmx这样的超媒体导向库,以获得超媒体模型的优势(简单性、可靠性、灵活性等)。
最近,Max Chernyak写了一篇题为《不要构建通用API来支持你自己的前端》的文章。他的摘要如下:
除非你在大公司工作且使用联合前端或GraphQL,否则你并不需要它(YAGNI原则)。
然后他讨论了通用API和应用API的不同需求。他列出了通用API的以下需求:
而应用API的需求则是:
我将这种需求不匹配称为数据/应用API阻抗不匹配问题。
Max的建议是将API分成两个"部分":通用API和应用API:
我建议你停止将前端视为某种通用API客户端,开始将其视为应用的一半。
想象一下,如果你能直接发送整个"页面"所需的JSON。为
/page/a
创建一个端点,并在那里渲染整个/page/a
的JSON。为每个页面都这样做。不要强迫前端开发者发送大量独立请求来渲染复杂页面。停止用人为限制来烦扰他们。保持一致。
我完全同意Max对问题的分析。
我特别想强调的是,通用API需要保持稳定,而应用API必须快速变化以满足应用需求。
Jean-Jacques Dubray在这篇文章中描述了API设计者面临的困境:
如今我工作中最糟糕的部分是为前端开发者设计API。对话总是不可避免地变成:
开发者 - 这个屏幕需要数据元素x,y,z...能否请你创建一个响应格式为{x: , y:, z: }的API?
我 - 好的
这完美概括了Max注意到的矛盾:API工程师希望设计通用、稳定的API,但受制于快速变化的UI及其复杂的数据需求,而这些需求通常最好在服务器端解决。
正如Max指出的:
你可以保持"页面a"只做它需要做的事。你对"页面a"进行彻底的错误、安全、性能测试。你甚至可以通过一个大型SQL查询获取"页面a"所需的所有数据。
因此,我完全同意Max关于存在数据/应用API阻抗不匹配问题的观点,并赞赏他建议通过将两者拆分为独立的关注点来解决这个问题,而不是转向GraphQL等解决方案。
然而,还有一个后续步骤:
一旦你将应用API与通用数据API分离,你就不再受公共数据API约束的限制,可以自由地重新考虑该应用API的整体形式。我们可以随心所欲地设计它,所以让我们在思考上更开阔一些。
请注意,应用API的核心问题是快速变化和页面(或资源)特定调整。事实证明,我们有一种非常适合解决这个确切问题的技术:超媒体!
通过HATEOAS实现的超媒体使得API变更不再是那么大的问题。当你改变超媒体API的形式时,这没问题:新的API只需反映在服务器返回的新的HTML中。你可以添加和修改端点,看吧(在近似情况下),你的客户端(即浏览器)不需要更新。
浏览器只是看到新的HTML,而操作它们的人类会适当地对新功能做出反应。
因此,虽然我认为Max的思路是正确的,但我也认为他做得还不够:一旦你在思想上迈出了通过拆分关注点来解决数据/应用API阻抗不匹配问题的第一步,再往前走一小步就能重新发现超媒体的优势。
你可能会反对说:"哦,但是超媒体应用不太好用,我们不想回到Web 1.0时代。"
这是一个完全合理的反对意见,但人们一直在解决这个问题,现在有许多库可以在超媒体模型内解决HTML的可用性问题。
如果你改用超媒体应用API(实际上就是"像以前一样使用HTML"),那么你将获得REST-ful Web模型的所有好处(简单性、可靠性等),以及成熟Web框架中服务器端渲染的优势(缓存、SQL优化等)。
而且,通过选择像htmx这样的超媒体导向前端技术,你可以在该模型内创建出色的用户体验。
旧事物再次焕然一新,但这一次,稍微好了一点。