新旧交替,你敢相信?下一个应用程序可能没有后端……
“历史总是惊人的相似,有重演之势。”
一位科技界的大佬和小芯如是说。
我于1999年建立了第一个网站,用了一些可供网站管理员使用的最先进的技术(这种情况确实不能称他们为开发人员):所见即所得编辑器(WYSIWYG editors)。
对于我(还有很多人!)而言,这最初是指Microsoft FrontPage,而我正面带尴尬的微笑,以一种怀旧又羞愧的心情告诉你这一切。
我的网站是一堆静态的 HTML 页面,这些页面有很多 JavaScript 和精彩的 GIF,它们在20世纪初的互联网时代备受瞩目,并且由静态的托管者提供服务,这些托管者本质上相当于意大利的 GeoCities。
在接下来的几年中,我逐渐做出了更好的选择,例如2002年发布的 Macromedia Dreamweaver MX(也就是现在的Adobe);其最大优点是生成更加符合标准的代码。
十年后的2009年,我仍在建立网站,但动态是那个时候的关键。所有页面都是使用 PHP 在服务器端生成的。不只是PHP:开发人员当时也在用.NET,Java,Python,Ruby等构建全栈式网络应用程序。
这些技术并不完全是新技术:ASP 在1996年前后出现,而 PHP 在1994年首次亮相!但是,20世纪头十年的后半期,正是在这个时候,有了简化网站开发的新框架推动,更多的小型团队和开发人员可以使用这些技术。
例如,Django和 Ruby onRails 于2005年问世。此外,在那几年,人们开始注意到动态网站的便宜主机托管选项(Bluehost这类共享主机开发于2003年),因此开发人员不必管理自己的服务器。
当时,云计算还是一个相对较新的事物,总之,它基本上都是基础设施即服务。
快进到当今时代。现在是2019年,开发人员现在正在……再次建立静态网站。你可能会称其为网站开发领域的尼采永恒回归的再现。
但这一次,情况有所不同:得益于更新的 HTML、JavaScript、CSS 标准和 API,网络浏览器的功能远远超过了20年前。
现在,电子表格和3D游戏这样极其复杂的应用程序可以开发出来并在网络浏览器中运行,而且无需外部插件。(大量的GIF也会再次使用,但这次暗含了一些讽刺意味!)
JAMstack 和 Isolated Front End
HTML5 最初发布于2008年,自那时起,浏览器厂商一直在实施新的网络标准并向网站中添加 API。
改变体现于更多的“基本”事物,例如<video>标签在很大程度上推动了Adobe Flash退出历史舞台,对WebAssembly之类的网络构建方式提出了根本性的建议,因此开发人员常常很难掌握最新消息以及可能发生的情况。
但是,最大的进步是网络应用程序新设计范式的推广,这种新范式被称为JAMstack,包括JavaScript、可重用 API 和预渲染(pre-rendered)Markup。
该设想从移动应用程序中获得灵感,即使网络应用程序的前端层与后端层完全隔离,人们也可以只凭借一组商定的界面用HTTPS进行通信。
JAMstack 应用程序体系结构的概念概述
JAMstack 的 JavaScript 部分所起的作用应该是不言而喻的:整个应用程序都在客户端(即网络浏览器)中运行,由 JavaScript 支持(你也可以更加概括地解释此定义,就像解释执行 JavaScript 代码的浏览器中相同的 VM 一样, WebAssembly也是如此)。
“A”绝对是最有趣的部分,它指的是API:API让 JAMstack 应用程序具有交互性,并为终端用户带来非凡的体验。你的静态应用程序可以通过 HTTPS调用的 API 与其他服务进行交互。
最简单的例子是 RESTful API,它们易于构建、方便使用。最近,GraphQL越来越流行,它对于可以用图表表示的数据特别有用(其发明于Facebook 并不是巧合)。
对于某些情况,例如,那些需要交换大量结构化数据的应用程序还可以选择Protocol Buffer和gRPC,尽管它们目前需要代理才能与网络浏览器一起使用。
最后,实时应用程序可能会利用WebSocket。你可以自由选择你想要的任何 API 格式,只要它满足你的需求即可。
说到 API,一个非常重要的细节是任何人都可以拥有它们。你的应用程序可能正在与你(或后端团队)构建和维护的 API 进行交互。或者,你可能正在使用第三方API,例如 SaaS 应用程序提供的 API。稍后将重点介绍这些内容。
最后,JAMstack 中的“M”代表预渲染的 Markup。网络应用程序是静态 HTML 文件,在“构建时”通过各种打包工具(例如webpack、Parcel或Rollup)对这些文件进行预渲染。
Markdown文件中的内容也可以渲染,就像静态网站生成器一样,例如Hugo、Gatsby以及Jekyll。在部署应用程序之前,所有预处理都在开发人员的计算机或持续集成 (CI) 服务器上完成。
使用 JAMstack 编写的应用程序一旦被“编译”,就变成了一堆 HTML、JavaScript 和 CSS 文件,附带着全部资源(图像、附件等)。服务器端任何时候都不会处理。这给 JAMstack 应用程序带来了极大好处。
首先,JAMstack 应用程序极其容易部署、缩放和操作,而且它的性能极好。
你可以从云对象存储服务(例如Azure Blob Storage或AWS S3)交付静态文件,这些服务价格(每GB每月只需花几便士)非常便宜,而且特别可靠。
使用对象存储服务时,你也不需要管理、修补服务器或框架,因此开销减少了,而且安全性也提高了。
然后,将 CDN(内容分发网络)放在对象存储的前面时,你的网站将由世界各地的多个终端节点直接提供服务和缓存,在全球范围内,你网站的访客将受到最小的延迟影响,此外,可扩展性也会达到极佳水平。
如果你愿意的话,也可以像我一样通过星际文件系统 (IPFS) 提供文件。
其次,JAMstack 的开发人员体验(DX)很容易进行。首先,前端开发人员和后端开发人员可以专心编写自己的代码,只要他们就接口和API达成一致意见,就基本上可以进行自主操作。
带有复杂模板引擎(还记得PHP吗?)的整体式应用程序时代已经一去不复返,这引起了两个团队间的冲突,让大家都很头疼。
前端应用程序在编译后只是一堆静态文件,因此它们也容易自动部署:级别较高时,你可以将新捆绑软件复制到存储区域,然后更新 CDN ,从而指向新资源。
前端应用程序的编译速度往往非常快,无需担心容器化技术、容器编排以及Kubernetes等问题。
考虑到工具的标准化程度,有了预制模板,建立持续集成和持续交付(CI / CD)管道通常很简单。
最后,前端开发人员可以自由进行实验,在某些情况下,他们甚至可以将开发前端指向生产后端。
一切都与速度有关
对于终端用户而言,真正的获益在于感觉到应用程序的快速运行。这不仅可以提高用户满意度,还可以提高用户的参与度和保留率。
为什么会感觉到应用程序的快速运行?本文将从以下三个方面来解答。
首先,应用程序本身异步加载数据,因此用户可以在加载数据时看到界面,并可以与其进行交互。下图是新版Twitter 应用程序加载的动图:
这个新的应用程序立即加载并异步请求数据
该应用程序本身几乎立即加载,然后逐渐开始异步请求数据,并填充整个界面。
第二个原因是大量缓存应用程序的能力。对于很多的JAMstack 应用而言,JavaScript 和 CSS 文件不会经常更改,所以客户端下载应用后可以长时间缓存。
这样可以节省请求应用程序代码的时间,客户端只需要提取数据即可。此外,如果该网络应用程序是通过 CDN 提供的,那么它会允许用户从靠近他们的终端节点检索你的代码,极大地降低了延迟。
应用程序的代码可能有好几KB,即使如此,从 CDN 下载它的时间延迟降低了,还可以本地缓存文件,这实际上意味着该应用程序的运行速度变快了。
关于缓存,你还可以使用诸如Service Workers之类的更多技术来实现应用程序代码和数据的缓存,进一步加快页面加载速度,甚至提供离线体验。
最后,API 服务器不需要花费时间生成并提供完整的 HTML 页面,它只需要处理原始数据(通常是 JSON payload,在传输过程中使用 GZIP 压缩),而把构建页面的工作交给客户端完成。
将资源交给对象存储服务时,后端服务器不会收到对静态资源的所有请求,因此它将拥有更多的资源来处理实际的业务逻辑和API。
你可能不需要自己的API
上面曾提到,JAMstack 中的“A”代表 API,而且你可以使用任何人构建和操作的任何 API。
你可以使用外部身份提供程序对用户进行身份验证。如果你要构建企业应用程序,那么目录可能已经位于Azure AD或G Suite Directory(或与之同步)。
至于消费者应用程序,可以考虑与Apple、Facebook、GitHub这样的社交平台合作。
也有像Auth0和Okta这样的公司,它们可以提供功能强大且可扩展的解决方案,包括帐户管理(注册表单、密码重置...)以及与各类外部供应商的集成。
令人欣慰的是,很多其他的 API 至少可以支持来自上述某些供应商的身份验证令牌,因此你可以立即进行集成操作。另外,无论如何,使用外部身份提供程序而不使用自己的身份验证代码都是一个好主意,因为这种做法最安全。
然后,你可以集成大量的 SaaS 服务,这会使你的应用程序得以接触到大量的数据,拥有更多的功能,而你这一端无需付出任何努力。
API 可以应用于天气、交通、显示股票价格、地图、监控航班,甚至还可以用来订比萨。
你可以使用 Google Analytics 或 Adobe Analytics 来计算网站的流量。如果要创建博客,那么你可以使用Disqus或Commento之类的服务,从而轻松实现用户对帖子的评论功能。
如果你需要内容管理系统来修改网站内容变得轻松愉快,那么“无头内容管理系统”可为你提供多种选择。例如,Strapi和Ghost。甚至随处可见的 WordPress 也可以在无头模式下使用。
企业应用程序与 Microsoft Office 365 和 G Suite 等办公套件集成后,你就可以收发电子邮件、管理日历和联系人、创建文档和电子表格、访问企业目录等。
这些服务还附带 OneDrive 和 Google Drive 中的云存储,因此你可以轻松地使用它们来存储和检索数据。
开发人员还可以依靠外部服务来接受信用卡付款(如 Stripe)、在文件格式之间进行转换、为图像生成缩略图(例如CloudConvert)、处理视频、发送消息(可通过 Slack、Teams、Twilio 等服务)......
API的功能是列不完的。用户可以从前端应用程序直接访问某些数据库服务,例如Firestore。
最后,你还可以将某些“低代码/无代码”服务用于服务器环境一定需要进行的过程,因为它们需要连接客户端无法直接访问的服务(数据库、某些企业应用程序等)。
一种解决方案是Azure Logic Apps,它本来是一个为开发人员和企业而设计的 IFTTT,你可以通过 REST 调用来让它运行。
使用外部服务提供的 API 的好处不容错过。确保它们可用并根据需要进行扩展是其他人员的责任。
你无需修补任何应用程序或框架,更不用说基础架构了,所有这些都会交给一个团队来维护,从而保证其安全性。
关于隐私和合规性,还有一些有意思的好处。
如果你的应用程序仅存在于客户端而未存储任何数据,那么 GDPR 合规性的责任多半将由你依赖的服务供应商承担,就像使用外部服务付款一样(如 Stripe),这让你免于遵从PCI-DSS。
当然,如果没有其他选择,也可以构建自己的 API。
借助无服务器平台,例如 AWS Lambda和AzureFunctions,你无需管理和扩展自己的服务器,不过仍有负责的东西。
负责的内容包括修补应用程序,确保其在受支持的运行时上运行(例如:你使用的Node.js达到使用年限时,你要更新版本),可以视需要考虑如何地理复制这些部署和负载均衡。
构建自己的 API 通常也需要管理数据存储,这些数据存储需要经过复制、备份和缩放。
接下来是什么?JEMstack
依靠自己的 API 和/或第三方 API 来使用 JAMstack 构建网络应用程序,是当今网络开发过程中最先进的设计模式之一。
数十年来,人们一直在将应用程序完整地移动到服务器上,并尽可能地将大部分工作从客户端上移走,然后又将更多的任务放到浏览器上。
无论是你自己还是其他人,还需要服务器的只剩下一个地方,那就是 API。那么按照逻辑,下一个问题是:“我们如何才能完全摆脱服务器?”
答案是:最终可能通过使用区块链实现,特别是以太坊(Ethereum)。
我建议称其为“JEMstack”,是 JavaScript、Ethereum 和预渲染 Markup 的首字母缩写。
该堆栈将是“ Web 3.0”或分布式 Web 的一部分。“JEMstack”分布式应用程序(或 dapps)将接受IPFS提供的服务,其数据将作为分布式总账存储在区块链中。
其中的一些好处包括将数据的控制权交还给用户,而且无论怎样,开发人员都不必为基础架构担心。
以上这些还远远没有实现。你完全可以使用区块链(尤其是以太坊)构建 dapp,事实上,这样的应用已经有很多了:App.co上有一个不错的精选列表。但是,要使此类技术成为主流,仍需要解决许多问题。
实际上,构建以以太坊为基础的应用程序的开发人员经验 (DX) 确实很棒。
应用程序可以通过简单无缝地调用智能合约来轻松访问和更改存储在区块链上的数据。此类智能合约由一些代码组成,它们为了以太坊区块链(从技术层面来说是以太坊虚拟机)而被编译,之后在上面运行。
智能合约可以存储数据并在上面进行计算,它通常由名为Solidity的语言编写,这种语言与C语言类似。
但是,我在写本文时发现,终端用户体验 (UX) 仍有很大的提升空间,这是广泛应用 dapp 的最大障碍,该障碍可能还会持续更长时间。
首先,大多数用户将需要安装浏览器扩展来与以太坊进行交互,例如 Firefox 和 Chrome 的Metamask和 Safari 的Tokenary。只有不那么流行的浏览器(如 Brave 和 Opera)才提供对以太坊钱包的内置支持。
Mobile 是另一个雷区,用户需要在其中下载特定应用程序(例如 Coinbase Wallet 或 Opera Mobile)才能与区块链进行交互。
然后,用户必须处理以太坊钱包。虽然从以太坊读取数据既免费又便于操作(并且不需要用户交互),但是在区块链上写入任何东西都需要得到用户的手动批准,而且至少要支付“油费”。
用户需要支付一小部分以太坊代币,才能执行改变区块链状态的代码,而且无论智能合约功能本身是否可支付,这都是必需的(例如:它将资金(以太币)转移给其他人)。
用户体验并不让人满意,因为它要求用户显式单击弹出窗口,然后等待几秒钟到几分钟,以便以太坊区块链能确认交易。
当然,用户需要先购买以太坊令牌,这并不像看起来那样简单,尤其是在世界上某些国家或地区。
最后,如果用户放错了钱包的私钥或还原了单词,或不够谨慎,都会留下安全隐患。
确认弹出窗口是 Metamask UX的常见部分
目前有一个庞大的团体正在致力于改善区块链应用的用户体验,使其更容易添加身份,构建更透明的流程,使交易更快,甚至能瞬间完成。
每种技术仍处于不稳定状态,而且现在存在着各种各样彼此竞争的区块链技术。这与平台和框架的情况很相似。
真心希望在接下来的几个月和几年中,会看到更多的融合和标准化,而最终写在“JEMstack”上的 dapp 可能会成为新的规范。