与使用 React 等单页面应用程序框架构建 Web 应用程序相比,使用传统的服务器端渲染 (SSR) 或换句话说,构建超媒体驱动应用程序 (HDA) 构建 Web 应用程序需要改变思维方式。
如果你带着 SPA 工程师的帽子来处理这种开发风格,你很可能会感到沮丧,并错失这种特定架构选择的许多优势。
以下 10 个技巧将帮助你顺利地进行思维转变,利用这种方法的优势,并尽量减少其缺点
超媒体驱动方法的一个主要优势是,在构建 Web 应用程序时,它使服务器端环境变得更加重要。你的后端不再只是简单地生成 JSON,而是你 Web 应用程序用户体验中不可或缺的一部分。
因此,深入了解服务器端环境中提供的功能很有意义。许多旧的 Web 框架在生成 HTML 方面拥有极其深厚的功能。像服务器端缓存这样的功能可以决定你 Web 应用程序的响应速度,是快如闪电还是迟缓拖沓。
花时间学习所有可用的工具。
一个很好的经验法则是,你的应用程序中的响应时间应该少于 100 毫秒,成熟的服务器端框架提供了帮助实现这一点的工具。
服务器端环境通常具有非常成熟的机制来进行代码分解(或组织)代码。大多数环境中都很好地发展了模型/视图/控制器模式,而模块、包等工具提供了一个组织代码的绝佳方式。
虽然 SPA 的用户界面通常通过组件进行组织,但超媒体驱动应用程序通常通过模板包含进行组织,其中服务器端模板根据应用程序的 HTML 渲染需求进行分解,然后根据需要相互包含。与基于组件的应用程序相比,这往往会导致文件更少,但体积更大。
另一个值得关注的技术是模板片段,它允许你只渲染模板文件的一部分。这可以进一步减少服务器端应用程序所需的模板文件数量。
与JSON API 不同,你为超媒体驱动应用程序生成的超媒体 API 应该具有针对你的特定应用程序 UI 需求专门化的端点。
因为超媒体 API 不是为通用客户端设计的,所以你可以抛开使 API 通用化的压力,并生成应用程序特有的内容。
你的端点应该针对你的特定应用程序的 UI/UX 需求进行优化,而不是针对域模型的通用数据访问模型。
一个相关的技巧是,当你拥有一个基于超媒体的 API 时,你可以积极地重构你的 API,这在编写基于 JSON API 的 SPA 时是强烈反对的。因为基于超媒体的应用程序使用超媒体作为应用程序状态的引擎,所以你能够,事实上也鼓励你随着应用程序开发者和用例的变化而改变 API 的形状。
超媒体方法的一个巨大优势是,你可以完全重构 API 以适应新的需求,而无需对 API 进行版本控制,甚至无需对其进行文档化。
当使用 SPA 方法构建应用程序时,数据存储通常位于 JSON API 后面。这种间接级别通常会阻止前端开发者充分利用数据存储中提供的工具。GraphQL 可以帮助解决这个问题,但它带来了与安全相关的 issues,而许多开发者似乎并不理解这些 issues。
另一方面,当你使用服务器端生成 HTML 时,创建该 HTML 的开发者可以完全访问数据存储,并利用 SQL 存储中的例如联接和聚合函数。
这将更多的表达能力直接交给了生成 HTML 的开发者。因为你的超媒体 API 可以围绕你的 UI 需求进行构建,所以你可以调整每个端点,以尽可能少地发出数据存储请求。
一个很好的经验法则是,每个请求都应该尽可能少于 3 次数据存储访问。
模态窗口如今已成为许多 Web 应用程序中流行的,几乎是标准的元素。
不幸的是,模态窗口与 Web 的大部分基础设施配合不佳,并引入了客户端状态,而将这种状态与基于超媒体的方法无缝集成可能很困难(虽然并非不可能)。
考虑使用替代方案,例如内联编辑,而不是模态窗口。
许多 SPA 开发人员在接触 HDA 方法时遇到的一个问题是,他们会查看他们当前的 SPA 应用程序,并设想用超媒体完全实现它。虽然 htmx 和其他面向超媒体的库大大缩小了基于超媒体的应用程序与 SPA 之间的交互差距,但这种差距仍然存在。
正如 Roy Fielding 在谈论 Web 的 RESTful 网络架构时所说,说道
不过,权衡是统一的接口会降低效率,因为信息以标准化形式传输,而不是以特定于应用程序需求的形式传输。
接受对特定 UX 的效率和交互性略低的解决方案,可以为你构建 Web 应用程序节省大量复杂性。
不要让完美成为好的敌人。
在你的 Web 应用程序中的某个时候,超媒体方法本身可能无法满足需求。
一个很好的例子是重新排序一个列表。这可以通过点击向上和向下箭头或在项目旁边添加序号下拉菜单来完成(我羞愧地承认我曾经创建过这两种方式!)。
但与人们习惯的拖放相比,这种体验糟糕透顶。
在这种情况下,使用前端繁重的方案作为“交互岛”是完全可以接受的。
考虑SortableJS 示例。在这里,你有一个复杂的交互区域,它支持拖放,并且通过事件与 htmx 和更广泛的超媒体驱动应用程序集成。
这是在 HDA 中封装更丰富的 UX 的绝佳方式。
脚本是Web 架构中明确的一部分,采用超媒体方法的开发者不应该害怕使用它。当然,脚本也分很多种。
尽可能地,你应该尝试使用超媒体友好型脚本 方法,将超媒体交换作为与服务器通信系统状态变化的主要机制。
例如,由alpine.js 和hyperscript 支持的内联样式脚本也值得探索,因为它将你的脚本重点放在超媒体(HTML)本身,并对你可以编写多少代码施加了美学约束。
最后,不要对使用超媒体抱有教条主义。归根结底,它只是一项拥有自己的优势和劣势的科技。如果应用程序的某个特定部分,或者整个应用程序,需要比超媒体所能提供的更高的交互性,那么就使用能够满足需求的技术。
熟悉超媒体的 capabilities,这样你就可以做出明智的决定。
希望这些技巧可以帮助你更有效、更顺利地采用超媒体和服务器端渲染作为工具。它不是完美的客户端-服务器架构,它涉及明确的权衡,但对于许多 Web 应用程序来说,它非常有效(远比今天大多数 Web 开发人员所预料的要多),并且在这些情况下提供了更简单的整体开发体验。