本文扩展了本博客上已发布的两个比较:我们对 PostgREST 兼容性及其替代方案 的审查,以及我们专门针对 Postgres GraphQL 层的比较。这里角度发生了变化:构建 API 层的三种方法之间的决策网格,Hasura 考虑的是其权限和业务扩展点而不是 GraphQL 语法,手写 API 本身就是一个选项,而不是表格底部简单的“else”行。
要点
- PostgREST 从 Postgres 模式自动生成 REST API——不可能有任意的业务逻辑,RLS 仍然是唯一的安全边界。
- Hasura 在其 GraphQL 引擎之上按角色和表添加了自己的权限系统、连接业务 Webhook 的操作、事件触发器和 RESTified 端点。
- 自定义 API(Node.js、Express、Fastify...)可以完全控制业务逻辑、验证和身份验证,但代价是您自己编写、测试和维护所有内容。
- 在 Aurabase 上,PostgREST 层是一个真实的实例; CRUD 之外的业务逻辑通过 RPC 中公开的 SQL 函数或通过 Edge Functions,而不是通过单独的 Node 服务器来托管。
- 这三种方法不一定是相互排斥的:将用于 CRUD 的 PostgREST 与用于敏感操作的自定义 API 结合起来是生产中的常见模式。
真正的选择:谁编写业务逻辑,在哪里编写
“PostgREST 或 Hasura 或自定义 API”这个问题隐藏了一个更有用的问题:谁编写您的业务逻辑,使用哪种工具,以及谁在生产中使用此代码?这三种架构的反应不同,这种差异决定了其他一切——安全性、实施速度、长期技术债务。
| API 的起源 | 从 SQL 模式生成 | 通过 GraphQL Hasura 引擎从模式生成 | 逐条路线、手写路线 |
|---|---|---|---|
| 自定义业务逻辑 | 仅 SQL 函数 (RPC) | 操作(webhook)+事件触发器 | 任何代码,不受工具限制 |
| 安全模型 | RLS Postgres,由 JWT 驱动的角色 | 特定于角色/表的权限,而不是对 RLS 的委托 | 您编写的代码(中间件、ORM、可选的 RLS) |
| 为了容纳另外 | 没什么——一个轻量级的二进制文件 | Hasura 引擎,拥有自己的元数据库 | 完整的应用服务器 |
| 学习曲线 | 如果团队已经知道如何编写 SQL,则较低 | Medium——新的权限和配置系统 | 工具上没有任何内容,但需要设计的其他内容 |
| 后格雷斯特 | 哈苏拉 | 定制API |
严格来说,这三个专栏都没有更好:每个专栏都将工作转移到其他地方。 PostgREST 将其移至 SQL,Hasura 移至配置和 Webhooks,这是经典应用程序代码的自定义 API。
PostgREST:API 作为架构的直接反映
PostgREST 将您的 Postgres 架构转换为 REST API(过滤器、关系嵌入、RPC、由 JWT 驱动的 RLS),无需编写后端。我们在文章中深入详细介绍了该范围,了解其真正的 兼容性及其 替代方案;对于此比较来说,重要的是 PostgREST 停止的位置。
PostgREST 没有任意业务逻辑的概念。每个规则都必须用 SQL 表示:RPC 函数、触发器、约束、RLS 策略。这是一个可接受的约束,而不是疏忽——图表仍然是唯一的事实来源,这消除了应用程序层与其服务的基础之间的任何偏差。
具体来说,无法通过直接的 PostgREST 请求调用第三方支付服务、发送确认电子邮件或在 JavaScript 中计算分数。该逻辑必须存在于 SQL(pl/pgsql 函数)中,或者在外部触发 - 一个发布 NOTIFY事件的触发器,由不再是 PostgREST 的外部服务监听。
Hasura:权限声明,通过 webhook 嫁接业务逻辑
我们关于 Postgres 上的 GraphQL 层 的文章详细介绍了 Hasura 引擎的运行位置以及其权限与 Postgres RLS 有何不同。这里的角度是业务逻辑的角度:如何将自定义代码插入到 Hasura 管理的数据库中,以及在哪里插入。
操作 Hasura 公开自定义 GraphQL 突变或查询,由您用您选择的语言编写的 HTTP Webhook 支持。 Hasura 根据声明的架构验证输入,调用您的 webhook,然后将其响应返回给客户端。它是通往 CRUD 以外任何逻辑的门户:调用支付提供商、复杂计算、多步骤编排。
事件触发器 遵循相反的方向:表上的插入、更新或删除会异步触发 Webhook,并在发生故障时自动重新启动。这是大多数 Hasura 集成用于同步第三方服务(计费、事务电子邮件、搜索引擎)的机制,无需将此代码与初始客户请求耦合。
Hasura 还可以将已经编写的 GraphQL 查询公开为典型的 REST 路由,并带有命名路径和参数——用其自己文档的术语来说,它的 RESTified端点。如果您的前端团队更喜欢使用 REST,而不放弃底层 GraphQL 权限引擎,则非常有用。
Hasura 权限是 Hasura 特定的系统,针对每个角色和每个表,而不是对 Postgres RLS 的委托。审计访问规则的两个地方,而不仅仅是一个——这是与操作和事件触发器所获得的灵活性进行权衡的实际成本。
上下文提醒,在我们的专门文章中提出:自 2025 年 6 月以来,Hasura 已将其通信重新集中在 PromptQL(一个为 AI 代理设计的层)上,但没有删除其 GraphQL 引擎,该引擎在其官方网站上仍然显示为“经过实战测试”。
自定义 API(Node.js、Express、Fastify):编码一切、控制一切
根据定义,手写 API 没有任何限制:任何业务逻辑、任何语言、任何依赖项。它也是三个选项中唯一一个不为您生成任何内容的选项 - 每个路由、每个验证、每个数据库连接都是您拥有且必须维护的代码。
该模型所提供的,以换取手动工作:完全控制错误和返回的 HTTP 代码、经典的可测试性(处理程序,而不是声明性配置),并且对于已经掌握其语言的团队来说,无需学习新的 DSL。
作为交换,它的成本是:为每个资源手动编写和维护 CRUD、分页和过滤器;身份验证和授权自行实施和审计,无需自动继承RLS;如果每个嵌套关系无规律地触发自己的 Postgres 查询,则存在 N+1 查询的风险;和 API 文档需要手动维护,或者通过第三方生成器进行集成。
在原始性能方面,“Node.js 比 Rust 慢吗”这个问题本身就是一个主题——我们关于 Rust 与 Node.js 延迟 的文章详细介绍了这个问题,并在我们的 基准测试方法页面上游声明了方法。自定义 API 与您已经使用的任何 HTTP 服务具有相同的性能配置文件,不会因为构造而变得更好或更差。要准确了解 PostgREST 在何处饱和以及何时需要自定义层,请参阅我们关于 PostgREST 在生产中的真正限制的文章。
比较表:三个选项并排
除了架构之外,选择时最常出现的四个标准:实施速度、实际业务灵活性、长期技术债务以及每个选项最舒适的典型用例。
| 初始设置 | 分钟 — 架构已存在 | 小时 — 连接底座、配置权限 | 几天到几周——写下每条路线 |
|---|---|---|---|
| 业务灵活性 | 仅限于 SQL(RPC、触发器) | 通过操作/事件触发器很好,但需要通过外部 webhook | 全面、简单 |
| 定期技术债务 | 弱——图表仍然是唯一的事实来源 | Medium——除了模式之外还需要维护的 Hasura 元数据 | 如果团队在没有纪律的情况下成长(测试、文档、审查),则较高 |
| 典型用例 | 在稳定的模式上直接进行 CRUD,团队熟悉 SQL | 联合多个数据源或面向 AI 代理的逻辑 | 业务逻辑复杂,第三方集成众多 |
| 后格雷斯特 | 哈苏拉 | 定制API |
Aurabase 项目中的业务逻辑在哪里
在 Aurabase Postgres 引擎项目中,CRUD 层已被实际的 PostgREST 实例覆盖,而不是近似的重新实现。对于这种比较,仍然存在一个问题:在哪里编写超出 CRUD 范围的内容?
存在两条路径,并且它们并不相互排斥。第一个:在 RPC 中公开的 SQL 函数,用于在 SQL 中合理表达的任何逻辑 — 计算总数、多个表之间的交叉验证、单个事务中的级联更新。
第二种方式:Edge Functions,适用于 SQL 域之外的所有内容 — 调用支付 API、发送电子邮件、计算嵌入。 Aurabase 有两条路径:Studio 编辑器,它运行与 Supabase 完全相同的 Deno (TypeScript) 代码;以及 aura functions deployCLI,它的目标是为用 Rust 编写并在 WASM 中编译的函数提供单独的路径——详细信息请参见我们的 统一 Rust 架构。这两种路径都不需要托管单独的 Node 服务器,这与本文中的纯“自定义 API”选项不同,该服务器完全由您负责。
这种分布并不是这里比较的三个模型之间不稳定的妥协:它实际上是用于 CRUD 的 PostgREST,是一个接近 Hasura Actions 的砖块,用于通过 RPC 和触发器进行事件逻辑,以及避免完整应用程序服务器操作的 Edge Functions - 无需强制在“所有 PostgREST”和“所有自定义”之间进行二元选择。
如何根据自己的情况选择
最常出现四种情况。正确的选择主要取决于您的业务逻辑需要什么,而不是工具的受欢迎程度。
- 您的架构是稳定的,您的业务逻辑是在 SQL 中。 自托管 PostgREST 或本机集成(Aurabase、Supabase)就足够了:无需再托管,模式仍然是唯一的事实来源。
- 您想要整合多个数据源,或者您的路线图适合人工智能代理使用您的数据。 Hasura 及其 PromptQL 层更适合这种地形。
- 您的产品具有丰富的业务逻辑、众多的第三方集成以及已经配备应用语言的团队。 自定义 API 仍然是最直接的选择,但代价是随着时间的推移编写和维护它。
- 您想要自行生成 CRUD,而又不放弃业务逻辑(RPC、边缘函数)的实际空间,也不希望再堆叠一项应用程序服务来利用。 这是上一节中应用于 Aurabase 的比较中记录的角度。