示例
此示例基于 Dart,但您可以随意想象成您自己的语言。
void main() async {
final app = await setupMyApp(); // expressjs, django, rails
// Setup node
final followedNode = await DBNode('users').get('id', 1).joinMany(
'followeds',
fromNode: DBNode('users').joinMany(
'places',
fromNode: DBNode('places'),
),
);
// Plug the node to an endpoint
app.sangre('/followeds', followedNode);
await app.listen();
}
这暴露了一个 WebSocket 端点,实时流式传输用户(id==1)及其关注的用户(带有关联的地点)。
当数据库中的数据发生变化时,WebSocket 会实时流式传输更新。请在此处查看工作示例:此处。
关于项目
Sangre 为实时将复杂的后端查询流式传输到客户端提供了通用的解决方案。
复杂查询是结构化数据库数据的任意嵌套查询,以及在您的原生后端语言(js、python 等)中处理这些数据。
此类查询的结果使用增量更新流式传输到客户端,从而最大限度地减少网络负载并实现离线同步。
典型用例是客户端-服务器拓扑,即移动或 Web 应用程序在数据库(postgres、mongo、mysql 等)前面使用 API(expressjs、django、rails 等)。您希望在您的应用程序中获得实时数据,而无需自行开发数据同步的全部复杂性。
Sangre 实现了所有以下功能,并让开发人员专注于业务逻辑。
| 特点 | |
|---|---|
| 关系数据库查询的实时处理 + 任意转换 | ✔️ |
| WebSocket 客户端流式传输 | ✔️ |
| 客户端离线同步 | ✔️ |
| 最小网络负载(增量更新) | ✔️ |
| 可嵌入到现有项目中 | ✔️ |
| 您需要采用新的数据库 | ❌ |
工作原理
Sangre 是一个有向无环图的运算符节点,对数据进行操作。这些数据作为数据流在这些节点中流动,以实现响应性。
节点可以是过滤器、连接、填充器。根节点通过底层数据库(通常是 postgres)提供数据,并通过 Supabase 实时监听更改,以便将其传播到数据流的下游。叶节点是客户端应用程序通过 WebSocket 消耗的端点。
限制(Alpha 版)
注意:Dart 是临时的,TypeScript 可能是最终实现。在开始概念验证时,我恰好在研究 Dart。
在此阶段,Sangre 只是一个概念验证。为了生成一个可运行的示例,已经做了很多妥协。以下是已知的限制,如果您想到其他限制,请通过我的联系方式与我联系。
| 需要克服的限制 | 可行性 |
|---|---|
| 水平可伸缩性 | ✔️ |
| 可观测性 | ✔️ |
| 向上查询 | ✔️ |
| 语言无关(每个语言都需要实现) | ❌ |
| 严格一致性 | ❌ |
| 参数化查询 | ✔️ |
| 在相似查询之间共享节点 | ✔️ |
Diff 算法目前是 JSON patch。这可以轻松更改为更易读或更高效的算法(myers、histogram、您自己的算法?)
安装 (待办)
注意:目前仅支持 postgres(更多支持即将推出)
注意:您可以使用 docker-compose.yml 来运行一个可正常工作的示例
1. 启用 postgres 复制 (待办)
ALTER SYSTEM SET wal_level = logical;
CREATE PUBLICATION supabase_realtime FOR ALL TABLES;
2. 安装实时消息代理 (待办)
insert supabase realtime installation steps
联系方式
项目链接: https://github.com/pomarec/sangre
致谢
-
灵感
- NoriaDB:非常感谢 Jon Gjengset 清晰地阐述了我的想法(白皮书)。但 Sangre 并不是该论文的实现。
- 所有关于物化视图和数据流的工作 (原始来源列表)
-
Dart 库
- alfred
- dartz
- json_patch
- postgres
- realtime_client
- rxdart
- web_socket_channel
- flutter
- flex_color_scheme
- hovering