你的下一款应用可能没有后端

今天,我们谈一谈JAMStack 和它的未来演变。

历史总是喜欢重演。

我在 1999 年建立了自己的第一个网站,使用的是当时的 Web 高手(这里我还没法用“开发者”这个词)能接触到的最先进技术:所见即所得的编辑器。对我(以及许多其他许多人!)而言,这种技术最早指的就是 微软 FrontPage ——现在回想起来,我的脸上还会浮现出掺杂着怀旧和羞愧的尴尬笑容。那时我的网站是一堆静态 HTML 页面,外加足量的 JavaScript 和酷炫的 GIF 的组合(它们在 2000 年的互联网上就是最靓的仔),放在静态托管服务商的平台上——我用的是意大利的 Geocities 同类服务。在接下来的几年里我逐渐成长,有了更好的选择,比如说 2002 年发布的 Macromedia Dreamweaver MX(现已并入 Adobe), 它的最大优点是其生成的代码更加符合标准。

十年后的 2009 年,我仍在构建网站,但那时的关键词是 动态。所有页面都是使用 PHP 在服务端生成的。不只是 PHP,开发者正在以.NET、Java、Python、Ruby……构建全栈式 Web 应用。这些技术并不是全新的。ASP 自 1996 年以来就已经存在,PHP 则诞生于 1994 年!但在 2005—2010 年,一系列旨在简化 Web 开发工作的框架涌现,使得更多的小型团队和个人开发者开始有能力应用这些技术,例如 Django 和 Ruby on Rails 就是在 2005 年问世的。此外,那些年我们看到针对动态站点真正廉价的托管方案(如 Bluehost 这样的共享托管商,成立于 2003 年)开始出现了,因此开发者不必再管理自己的服务器。当时,云计算仍然是一种相对较新的事物,基本上属于基础架构即服务的类型。

快进到今天。现在是 2019 年,开发者现在正在再次构建静态网站。你可能会把这种现象称为尼采的永恒轮回在 Web 开发行业的映射。但这次情况有所不同:拜更新的 HTML、JavaScript、CSS 标准和 API 所赐,Web 浏览器的能力大大超过了 20 年前。我们可以构建出运行在 Web 浏览器中的极其复杂的应用,从电子表格到 3D 游戏无所不包,而且我们无需依赖外部插件。(我们也会像当年一样大量使用 GIF,但这一次是为了嘲讽!)

JAMstack 和孤立的前端

HTML5 的初稿发布于 2008 年,自那时以来,浏览器供应商一直在不断实施新的 Web 标准,不停向 Web 中添加各种 API。从比较“基本”的东西(例如对 Adobe Flash 的衰落做出了巨大贡献的 video 标签)到对 Web 构建方式提出的基础性修改提案(如 WebAssembly ),不断涌现的新事物使开发者常常很难掌握最新的可用技术。

不过进步之一是针对 Web 应用的新设计范式的普及,它被称为 JAMstack:JavaScript、可复用 API 和预渲染的标记(Markup)。这种范式的灵感来自于移动应用,其理念是 Web 应用也应该完全隔离前端与后端层,两者间仅通过一组协议接口,经由 HTTPS 通信。

JAMstack 的 JavaScript 部分应该是很容易理解的:整个应用程序都在客户端(即 Web 浏览器)运行,并由 JavaScript 驱动(你也可以推广这个定义,把它看成是浏览器中执行 JS 代码的虚拟机,这样也能把 WebAssembly 算进来)。

其中的“A”绝对是最有趣的部分,指的是 API:它们使 JAMstack 应用具有交互能力,并为用户提供出色的体验。你的静态应用可以通过 HTTPS 调用的 API 与其他服务交互。最简单的例子是 RESTful API,这些 API 很容易构建和使用。最近 GraphQL 越来越流行,在用图形表示数据时它很好用(它是 Facebook 发明的,这并不是巧合)。对于需要交换大量结构化数据的场景来说,协议缓存和 gRPC 是另一种选择,尽管它们目前需要代理才能与 Web 浏览器搭配工作。最后,实时应用可能会用到 WebSocket。你可以自由选择想要的任何 API 格式,只要它适合你的需求即可。

说到 API,一个非常重要的细节是它们可以属于任何人。你的应用可能正在与你(或后端团队)构建和维护的 API 交互。或者你可能正在使用一些第三方 API,例如 SaaS 应用程序提供的选项。我们稍后将重点介绍这些内容。

最后,JAMstack 中的“M”指的是预渲染的标记(pre-rendered Markup)。Web 应用是一些静态 HTML 文件的组合,这些文件通过各种构建工具(如 Webpack、Parcel 或 Rollup)在“构建时”预渲染。还可以从 Markdown 文件渲染内容,Hugo、Gatsby 和 Jekyll 这类静态站点生成器就是这样做的。在应用部署之前,所有预处理工作都在开发者的机器或持续集成(CI)服务器上执行完毕。

使用 JAMstack 编写的应用一旦被“编译”,就只是一堆 HTML、JavaScript 和 CSS 文件,以及所有附带的资源(图像和附件等)。任何时候都没有服务端处理过程。这给 JAMstack 应用带来了巨大的好处。

首先,JAMstack 应用非常易于部署、扩展和运营,并具有出色的性能。你可以从云对象存储服务(例如 Azure Blob 存储或 AWS S3)交付静态文件,这些服务非常便宜(每 GB 数据的月费很低),且高度冗余和可靠。使用对象存储服务时,你也不需要管理和修补服务器或框架,从而减少了开销并提升了安全性。然后你在对象存储前放一个 CDN(内容分发网络),你的网站就会由世界各地的多个终端节点直接提供服务和缓存,最大程度减小了全球所有访问者的延迟,并且可扩展性极佳。如果你愿意,也可以像我一样通过行星际文件系统(IPFS)提供文件。

其次,JAMstack 的开发者体验(DX)如丝般顺滑。对于初学者来说,前端和后端开发者都可以专注于自己的代码,只要他们约定好接口和 API,基本上可以实现自主运营。带有复杂模板引擎(还记得 PHP 吗?)的单体应用的时代已经一去不复返了,彼时那种引擎只会给两边的团队带来冲突和烦恼。由于前端应用在“编译”之后最终只是一堆静态文件,因此它们也很容易进行原子部署。宏观来说,你可以将新包复制到存储区,然后更新 CDN 以指向新资产。前端应用的“编译”过程往往很快,并且无需操心容器化和容器编排以及 Kubernetes 等。考虑到工具的标准化程度,建立持续集成和持续交付(CI/CD)管道通常非常简单,这要归功于预制模板。最后,前端开发者可以自由进行实验,在某些情况下,他们甚至可以将开发前端指向生产后端。

要的就是速度

对最终用户而言,这种模式真正的好处是构建出让人感觉运行飞快的应用。这不仅可以提高用户满意度,还可以提高用户的参与度和保留率。

可以从三个方面来解释为什么人们会感觉应用运行得很快。

首先,应用本身是异步加载数据的,因此用户可以在加载数据时看到界面,并可以与其交互。看一下新的 Twitter 应用加载时的 GIF:

应用本身几乎是立即加载的。然后它开始逐渐异步请求数据,并填充界面中的所有部分。

第二个原因是全方位缓存应用的能力。对于许多 JAMstack 应用而言,JavaScript 和 CSS 文件不会经常更改,因此客户端在下载它们后可以将其缓存很长时间。这样可以节省请求应用代码所需的时间,因此客户端只需提取数据即可。此外,如果 Web 应用是通过 CDN 提供的,则它允许用户从更靠近他们的终端节点获取你的代码,从而大大减少了延迟。即使应用的代码体积可能很大,但从 CDN 下载它的延迟变短,又能在本地缓存文件,实际上意味着应用的速度会更快。

至于缓存,你还可以使用 Service Worker 等技术来实现应用代码和(某些)数据的缓存,以进一步加快页面加载速度,甚至提供脱机体验。

最后,API 服务器不需要浪费时间来生成和提供完整的 HTML 页面,它只需要处理原始数据(通常是 JSON 负载,并在传输过程中使用 gzip 压缩)即可,让客户端来完成页面的构建过程。当你将资产包含在对象存储服务中时,后端服务器不会收到对静态资产的所有请求,因此它有更多资源来处理实际的业务逻辑和 API。

你可能不需要自己的 API

我在上面写道,JAMstack 中的“A”代表 API,并且你可以使用任何人构建和运营的 任何 API。

你可以使用外部身份验证服务来验证用户的身份。如果你构建的是企业应用,你的目录可能已经在 Azure AD 或 G Suite 目录中了(或与之同步)。对于消费类应用,请考虑使用诸如苹果、Facebook、GitHub 等社交平台的登录服务。还有 Auth0 和 Okta 之类的公司提供了功能强大且可扩展的解决方案,包括帐户管理(注册表单、密码重置……)和集成多种第三方服务的功能。好消息是,还有许多 API 可以支持上述某家或某些服务提供的身份验证令牌,因此你可以立即进行集成。另外不管怎么说,使用外部身份验证服务,而不是编写自己的身份验证代码是一个好主意,因为这是最安全的做法。

然后,你可以集成大量的 SaaS 服务,从而使你的应用访问大量的数据和功能,你自己却用不着做什么工作。

还有用来播报天气和交通信息、显示股票价格和地图、监控航班,甚至订购比萨的 API。你可以使用 Google Analytics 或 Adobe Analytics 来监测网站的流量。如果你要建立一个博客,则可以使用 Disqus 或 Commento 之类的服务,让用户轻松地对你的帖子发表评论。

如果你需要 CMS 来简单、动态地修改网站内容,则在“无头内容管理系统”中有多种选项可选,例如 Strapi 和 Ghost。甚至无处不在的 WordPress 也支持无头模式。

对于企业应用,与微软 Office 365 和 G Suite 之类的 Office 套件集成后,你就可以发送和接收电子邮件、管理日历和联系人、创建文档和电子表格并访问企业目录等等。这些服务还附带了 OneDrive 和 Google Drive 中的云存储空间,因此你可以轻松地使用它们来存储和获取数据。

开发者还可以依靠外部服务来完成以下工作:接受信用卡付款(Stripe)、转换文件格式并为图像生成缩略图(例如 CloudConvert)、处理视频、发送消息(例如通过 Slack、Teams、Twilio 等)……列表是无止境的。还可以从前端应用直接访问某些数据库服务,如 Firestore。

最后,你还可以将某些“低代码 / 无代码”服务用于服务器环境中必要的所有处理工作,比如有时它们需要连接客户端无法直接访问的服务(数据库和某些企业应用等)。一种解决方案是 Azure Logic Apps,它本质上是针对开发者和企业的 IFTTT,你可以通过一个 REST 调用来触发它。

使用外部服务提供 API 的好处是显而易见的。现在,确保 API 可用并按需扩展成了其他人的责任。你无需修补任何应用程序或框架,更不用说基础架构了,还会有一支团队专门保证它们的安全性。

还有一些有趣的好处是关于隐私与合规话题的。如果你的应用只限于客户端,也不存储任何数据,则符合 GDPR 规范的责任大都是由你所依赖的服务提供商承担的, 比如使用 Stripe 这样的外部服务付款时,你就用不着操心 PCI-DSS 的问题了。

当然,如果没有其他选择,你也可以构建自己的 API。有了 无服务器 平台(例如 AWS Lambda 和 Azure Functions),你就无需管理和扩展自己的服务器了——虽说你还是需要负责某些事情,比如说要修补应用程序,确保其在受支持的运行时上运行(你正在使用的 Node.js 版本到期后,你就得支持新版了),有时还要考虑如何对这些部署进行跨区域复制,并在各区域间平衡负载。建立自己的 API 时通常也需要自己管理数据存储,这些数据存储需要复制、备份和扩展。

接下来会是什么:“JEMstack”

依靠我们自己的 API 和 / 或第三方 API 来使用 JAMstack 构建 Web 应用,是当今 Web 开发行业最先进的设计模式之一。我们用了几十年时间将应用全面迁移到服务器内,并尽量将大部分工作从客户端上移走,如今我们又开始将更多的任务放到浏览器中了。

有一个部分还是需要服务器的,那就是 API,不管是你自己的也好,其他人的也罢。接下来我们自然会问一个问题,那就是我们如何才能完全摆脱服务器?

最终的答案可能会是区块链,具体来说就是以太坊。

我建议将这种模式称为“JEMstack”,也就是 JavaScript、Ethereum(以太坊)和 pre-rendered Markup(预渲染标记)的首字母缩写。这个技术栈将是“Web 3.0”或 " 分布式 Web" 的一部分。你的“JEMstack”分布式应用(dapps)将通过 IPFS 提供服务,其数据将作为分布式分类帐存储在区块链中。这样做的好处包括让用户控制他们自己的数据,开发者也不必操心任何基础架构。

但我们离这一步还很远。你可以完全使用区块链(尤其是以太坊)构建 dapp,事实上也已经有了很多 dapp。在 App.co 上有一个不错的精选列表,但要让这种技术成为主流,仍需要解决许多问题。

构建基于以太坊应用的开发者体验(DX)确实很棒。应用可以简单且无缝地调用智能合约来轻松访问和更改存储在区块链上的数据。这类智能合约由为以太坊区块链(在技术上来说是 E 以太坊虚拟机)编译,并在以太坊区块链上运行的代码组成。智能合约可以存储数据,并对其进行计算,这些合约通常使用称为 Solidity 的类似 C 的语言编写。

但在撰写本文时,这种模式的终端用户体验(UX)仍有很大的改进空间,这是 dapp 广泛流行的最大障碍,而且这种状况可能还会持续很久。

首先,大多数用户需要安装浏览器扩展才能与以太坊交互,例如用于 Firefox 和 Chrome 的 Metamask,以及用于 Safari 的 Tokenary。只有一些用户较少的浏览器(如 Brave 和 Opera)才提供对以太坊钱包的内置支持。移动是另一个雷区,用户需要在平台上下载特殊应用(如 Coinbase Wallet 或 Opera Mobile)才能与区块链交互。

然后,用户必须自己面对以太坊钱包。从以太坊读取数据是免费且简单的操作(并且不需要用户交互),但是在区块链上写任何东西都需要得到用户的手动批准,并至少要支付一笔“油费”。用户需要支付一些以太坊代币,才能执行使区块链状态发生变化的代码,并且无论智能合约本身是否是用来支付的(也就是将资金转移给其他人),这笔油费都是必需的。这样的 UX 并不能使人愉快,它要求用户点击一个弹出窗口,然后等待几秒钟到几分钟才能被以太坊区块链确认交易。而且,当然用户需要首先购买以太坊代币才行,实际做起来也不是那么简单,尤其是在世界上某些国家 / 地区更是麻烦。最后,如果用户把钱包的私钥或密码恢复单词放在了错误的地方,或者处理它们时不够谨慎,还会存在安全隐患。

Meatmask 的用户体验中,确认弹框是常见的操作。

有一个庞大的社区正在致力于改善区块链应用的用户体验,使其更容易添加用户身份信息、建立更透明的流程、使交易更快甚至即时进行等等。就像所有发展初期的技术一样,这里也有很多区块链技术、平台和框架互相竞争。希望在接下来的几个月和几年中,我们能看到更多的融合和标准化进程,直到最后,用“JEMstack”写出来的 dapp 可能会演变为新的规范。

我来评几句
登录后评论

已发表评论数()

相关站点

+订阅
热门文章