SQL 作为 API

将 SQL 本身作为公共 API 边界,承诺为客户端提供强大而灵活的查询能力,但也带来了关于安全性、性能和复杂度控制的棘手问题。评论者将这种做法与自定义 JSON DSL、GraphQL、PostgREST 风格的 URL 过滤,以及数据库原生访问控制(RBAC、行级安全、超时)进行比较,争论应当赋予用户多大权限,以及约束应在何处强制执行。许多人认可 SQL 风格查询语言或翻译为 SQL 的有限子集的价值,但对于是否应当在互联网上暴露原始 SQL,意见分歧很大。

总体框架

  • 讨论使用 SQL(或类似 SQL)作为 API/查询语言,而不是自定义的 JSON 过滤结构或 REST 端点。
  • 许多人认为这无论如何都不可避免是在“发明一种查询语言”;真正的问题是:该选哪一种,以及把约束强制在哪里?

SQL vs 自定义 DSL / JSON / GraphQL

  • 支持 SQL 子集:
    • SQL 表达力强、广为人知,并且天然可扩展;增加更多语言特性仍可保持向后兼容。
    • 避免设计一种可能日后失效、或变得难以演进的临时结构。
    • 本地 SQL(例如浏览器/WASM 中的 SQLite)再加同步,可以模糊 API 与数据库之间的边界。
  • 支持 DSL / JSON:
    • 自定义 JSON/AST 或类似 Lisp 的格式更容易解析、做类型检查,并转换为 SQL 或其他后端(例如 Elasticsearch)。
    • “看起来像 SQL 但其实不是 SQL”的 DSL 会让人困惑;最好明确且结构化。
    • 现有标准(OData、JSON:API、Google 的过滤 AIP/CEL、表达式语言、Substrait)已经解决了许多需求。
  • GraphQL 的评价褒贬不一:
    • 有人认为它等同于“打包查询”(解决 n+1/网络往返问题)。
    • 也有人认为它主要是一种结果塑形语言,查询能力有限(没有 union/递归),而且技术栈开销很大。

安全、权限与 QoS

  • 担忧:暴露 SQL 被认为不安全、难维护,并且存在性能风险(全表扫描、DoS、过大的表面面积)。
  • 反驳观点:
    • 现代数据库提供 RBAC、行级安全、约束、视图、超时、配额和限流;这些机制可以限制损害。
    • 语句超时和资源限制可以遏制病态查询。
  • 对于“数据库级安全”是否比将受限 DSL 编译为 SQL 更简单,争议仍然存在。

面向用户的查询体验

  • 对非技术用户(例如产品搜索)来说,自由形式的 SQL 被认为太难;UI 控件更自然地映射到简单的 AND/OR/分类筛选。
  • 一些实践者表示,产品搜索中的复杂 OR 逻辑很少被要求;而另一些人则经常在工具中怀念更丰富的布尔搜索。
  • 对于高级用户(日志、审计、管理/报表),文本查询语言(类似 SQL、Lucene、JQL 风格)被认为非常有价值。

现有工具与模式

  • 提到的示例:PostgREST、主要厂商的类 SQL API、ClickHouse 的控制、crt.sh 的公开 Postgres 访问,以及“把数据库直接交付出去”的模式。
  • 有人认为把这件事“做对”大致会接近 PostgREST 这类工具已经提供的能力;也有人为小型、上下文特定的实现辩护。