Convex完成2600万美元融资,能否重构Web3应用构建方式?
2022年4月27日,Web开发人员管理平台Convex宣布完成数额为2600万美元的A轮融资,本轮融资由a16z领投,并且a16z普通合伙人Martin Casado将加入Convex董事会。除此之外,还包括GitHub前CEO Nat Friedman、Alphabet董事会成员Ram Shriram,以及Creative Artists Agency创始人Michael Ovitz等天使投资人。Convex预计将在接下来几周时间内向更多开发者开放测试版。
Cenvex简介
开发人员在使用JavaScript或TypeScript函数与共享状态进行交互时,可以将该状态绑定到他的反应式应用程序中。除此之外,Convex完全无服务器,可自动处理缓存和缩放。
Convex致力于从根本上改变软件在网络上的构建方式以及构建人员的操作逻辑。Convex希望可以使各种规模的工程团队能够构建快速、可靠的动态应用程序,而无需复杂的后端工程或数据库管理。
Convex的团队在管理复杂应用程序和成长中团队中的关键共享用户状态方面拥有相当丰富的经验。其曾领导过EB级存储项目、设计过具有数万亿条记录的定制全球数据库、构建了一些较为流行的Web应用程序以及将桌面和移动软件交付到数十亿台设备上的技术专家。
Convex创建了一个由本地React前端组成的应用程序,该前端将数据存储在远程Convex部署中。
该应用程序完全由本地目录中的文件定义,其本质上是在云中运行的分布式应用程序。持久共享状态存储在Convex中,可用于运行开发者的应用程序以及任何希望与之交互的浏览器。
工作原理
Convex由三个主要成分组成:
文件存储:代表应用程序数据的图表和文档
Convex函数:确定性的JavaScript/TypeScript函数,用于修改和查询这些图表和文档
客户端库:在应用程序内运行以订阅查询函数和请求突变的代码
接下来,笔者将逐一进行简单介绍:
一、文件储存
开发者的Convex部署包含保存应用数据的图表。最初,其部署是不包含图表或文档的。一旦其将第一个文档添加到其中,相应的图表就会立即存在。开发者无需预先指定任何模式,或主动创建任何图表。Convex文档与JavaScript对象非常相似。它们具有字段和值,开发者可以在其中嵌套数组或对象。它们还可以包含对其他表中其他文档的引用。
二、Convex函数
但是如何通过使用数据输入和输出这些图表呢?在Convex中,开发人员可以通过使用函数来实现。Convex函数是使用JavaScript或TypeScript编写的,由Convex在开发者的部署中运行。其在用户浏览器中运行的应用程序不会直接向数据库读取和写入值。相反,它调用开发者的函数。开发者的函数可以通过传递给Convex函数与其数据进行交互。这会公开数据的稳定版本。同时,这些函数可以执行复杂的聚合、使用NPM库等等。他们可以做大部分JavaScript可以做的事情,但也并非全部。
另外,Convex函数必须是确定性的。确定性意味着无论开发者的函数运行多少次,只要给它相同的参数,它就会有相同的反馈并返回相同的值。包括调用HTTP API、将数据写入磁盘或将数据存储在Convex表中。
Convex函数不能执行任何网络调用或磁盘 I/O。但是该DatabaseWriter对象支持确定性更新,因此开发者的函数可以针对Convex表中包含的数据进行操作。Convex函数可以使用某些形式的随机性和时间。
Convex提供了一个“种子”强伪随机数生成器(Math.random())以便它可以保证函数的确定性。随机数生成器的种子是函数的隐式参数。
当开发者的Convex函数开始确保其函数中的逻辑是可重现的时,系统时间也将被“冻结”。Date.now()将在整个函数执行过程中返回相同的结果。
而当开发者编写Convex函数时,不必考虑维护这些确定性属性。Convex会在其进行时提供有用的错误消息,因此开发者可以避免因意外而做一些被禁止的事情。
Convex函数主要包括两种类型:
1、查询函数
查询函数不会写入Convex表,它们只会从中读取。
确定性在查询函数中是必要的,因为它可以支持Convex的两个重要特性。查询函数可以反应式加载。这意味着Convex将在结果更改时将函数的结果推送到客户端。Convex之所以能够做到这一点,是因为Convex:
知道执行该函数的数据库状态。
知道结果完全取决于数据库的状态和函数的参数。
当底层数据发生变化时,Convex可以安全地重新执行函数,而不必担心重复副作用。
Convex自动缓存查询函数结果。因为查询函数在给定相同参数和数据库状态的情况下总是返回相同的结果,所以Convex可以确信缓存值是完全正确的。当底层数据发生变化时,Convex会检测到缓存值不再有效并重新计算它。
2、突变函数
突变函数是开发人员在Convex中更改数据的方式。
当开发人员用mutation包装器包装一个Convex函数时,它将被Convex归类为突变函数。每个突变都是在一致的数据库快照上运行的事务。这意味着突变将始终以原子方式提交。无需考虑在事务中间更改开发人员身下的数据,也无需管理锁。
客户端库
开发人员的应用程序可以通过客户端库与Convex交互。客户端库位于开发人员的前端代码中,是应用程序的接口,其主要有两种用途:
从查询函数响应加载数据。
通过调用变异函数来编辑数据。
Convex可以帮助开发人员管理其全局状态并消除对传统数据库的需求。Convex旨在与无服务器平台合作,并可以同Netlify或Vercel等服务配对。这些服务提供:
托管:它们为开发人员的HTML和其他静态资产提供服务。
无服务器函数:虽然Convex查询和变异函数处理加载和编辑存储在Convex中的数据,但开发人员仍可能需要与第3方进行交互(这不能在Convex函数中完成,因为这是不确定的)。
通过ConvexReactClient创建WebSocket连接到开发人员的Convex部署。这是基于TCP的2路通信通道。这很重要,因为它允许Convex将新的查询结果响应式地推送到客户端,而客户端无需轮询更新。如果互联网连接断开,客户端将自动处理重新连接和重新建立Convex会话。
useQuery开发人员的应用程序使用React挂钩从Convex加载数据。这个挂钩允许开发者的应用在其Convex部署中调用查询函数。该useQuery挂钩为其UI组件带来了自动反应。像React这样的现代响应式Web开发框架可以轻松地在本地状态更改时重新呈现UI组件,但是构建完全响应式应用程序还需要将更改从数据库状态一直传播到UI。该useQuery挂钩向Convex后端发送WebSocket消息以创建活动订阅。Convex透明地监控查询所依赖的所有后端数据,并在查询结果发生变化时自动更新组件。
在引擎下,这个useQueryReact钩子:
告诉后端运行listMessages查询功能。作为执行的一部分,Convex将跟踪用于计算结果的文档和表格范围。我们称之为读取集。
在后端创建订阅以跟踪此客户对查询的持续兴趣。
稍后,如果任何突变插入、更新或删除与读取集重叠的记录,Convex知道它需要重新计算listMessages查询。如果结果listMessages更改,则将新值同步到客户端并重新呈现组件。
当useQuery挂钩卸载时,Convex客户端将通知该后端它不再需要此订阅。此数据流可确保开发者的组件在底层数据更改时自动重新渲染。
Convex订阅提供了一种强大的机制来使动态UI组件保持最新,但订阅的简单实现可能会向用户暴露一致性异常。
当客户端上的数据表示与后端数据的有效快照不对应时,就会发生一致性异常。使用基本HTTP API的应用程序通常有两种类型的一致性异常:
两个不同的HTTP请求可能具有不一致的数据,因为它们的执行时间略有不同,而底层数据同时发生了变化。
单个请求HTTP本身可能包含不一致的数据,当在后端执行单个请求时底层数据发生更改时,就会发生这种情况。
这些异常会在前端产生很多细微的错误。许多框架要求开发人员在前端实现hack和变通方法,以处理后端永远不存在的数据场景。例如:
聊天消息可能会引用前端尚不存在的用户ID。
同一用户的聊天消息列表可能具有不同的名称。
除此之外,手动处理这些情况既会使前端逻辑复杂化,也会给用户造成混乱的UI。幸运的是,这些问题在Convex中都会得到缓解,因为Convex会自动确保开发者的所有查询在给定时间点与后端保持一致。
Convex同时跟踪所有订阅,并以一致的顺序将所有更改同步到客户端:如果支持一个组件的查询结果在查询另一个组件之前发生更改,则它们将按相应的顺序在本地更新。此外,如果单个突变同时更新多个查询,这些更改将自动传播到客户端。Convex保证客户端始终看到一致的后端数据视图,表示某个时间点的数据库状态。
useMutation开发者的应用程序使用React挂钩在Convex中编辑其数据。这个挂钩允许开发者的应用在其Convex部署中调用突变函数。客户端将自动处理重试突变,直到它们被保存。
在内部,开发者的Convex部署会跟踪已提交的变更,并确保每个变更仅执行一次,即使客户端重试也是如此。我们称这种突变为幂等性。
突变幂等性很重要,因为它解决了一类常见的错误,即不稳定的互联网连接和重试逻辑导致突变意外执行两次。如果使用者在聊天应用程序中发送了两次消息,就会遇到此错误。突变幂等性保证了此类错误不会发生在Convex中。
此外,虽然客户端在飞行中具有突出的突变,但客户端会在用户关闭浏览器选项卡之前警告用户。这意味着当使用者调用一个Convex突变时,其可以确保用户的编辑不会丢失。
如上所述,Convex查询是完全反应式的,因此所有查询结果将在突变后自动更新。
有时开发者可能希望在突变同步到Convex后端之前更新UI。为此,其可以配置自动更新以作为突变的一部分执行。自动更新是对查询结果的临时本地更改,用于使开发者的应用程序更具响应性。
微信掃描關注公眾號,及時掌握新動向
2.本文版權歸屬原作所有,僅代表作者本人觀點,不代表比特範的觀點或立場
2.本文版權歸屬原作所有,僅代表作者本人觀點,不代表比特範的觀點或立場