贡献者指南

API 健康策略

师成师成· 更新于 2026-09-28· 阅读 7 分钟· 0 次阅读

登录后可跨设备保存划线和私人笔记登录

API 健康策略

DataFusion 被其他应用程序广泛用作库,拥有庞大的公共 API。我们努力保持 API 的良好维护,并尽量减少破坏性变更,以避免给下游用户带来问题。

破坏性 API 变更

什么是公共 Rust API,什么又是破坏性 API 变更?

如果一个条目出现在 docs.rs 页面上,它就属于公共 Rust API。

破坏性变更要求用户修改代码才能编译和运行,这类变更在 Cargo 手册的 SemVer 兼容性章节中被列为“主要变更”。常见示例包括:

  • 为函数添加新的必填参数(foo(a: i32, b: i32) -> foo(a: i32, b: i32, c: i32))
  • 删除一个 pub 函数
  • 更改函数的返回类型
  • 向 trait 添加没有默认实现的新函数

非破坏性变更的示例包括:

  • 将函数标记为已弃用(#[deprecated])
  • 向 trait 添加带有默认实现的新函数

什么是公共 SQL API,什么又是破坏性 SQL 变更?

DataFusion 同时也被用作 SQL 引擎,因此 SQL 语义(给定查询所返回的结果)的变更也是一种破坏性变更。即使 Rust API 没有任何变化,改变现有 SQL 构造的行为也可能悄无声息地破坏下游的应用程序、仪表盘和测试。

对于 SQL 语义变更,我们与 Rust API 变更一样谨慎:必须权衡其收益与给下游用户带来的破坏成本。

何时进行破坏性 API 变更?

在可能的情况下,我们倾向于避免进行破坏性 API 变更。避免此类变更的一种常见方式是弃用旧 API,如下文的弃用指南部分所述。

如果你确实想提出一项破坏性 API 变更,我们必须权衡该变更的收益与成本(对下游用户的影响)。下游用户往往不愿意改动自己的应用程序,如果改动之后还不能获得更强的能力,那就更令人沮丧了。

破坏性 API 或 SQL 变更的合理理由示例:

  • 它开启了以前无法实现的新用例
  • 它显著提升了性能
  • 之前的行为明显是错误的(例如产生错误的结果)

可能站不住脚的理由示例:

  • 一项使 DataFusion 更加一致的内部重构
  • 移除一个使用范围不广、但尚未标记为已弃用的 API
  • 略微提升与另一个数据库(例如 PostgreSQL 或 DuckDB)的兼容性

制作破坏性 API 变更时该怎么做?

在进行破坏性的 Rust API 变更时,请:

  1. 添加 api-change 标签,以便该变更在发布说明中被突出显示。
  2. 将非同寻常的变更记录在对应版本的升级指南中。

对于破坏性的 SQL 变更,还请在 PR 描述中说明变更前后的行为,最好在适当之处附上示例查询及其结果。这样既便于审查,也能帮助下游用户了解受影响的语义。

升级指南

如果某项变更要求 DataFusion 用户在升级过程中修改其代码,请考虑将其记录在对应版本的升级指南中。

弃用准则

弃用某个方法时:

  • 使用 #[deprecated] 将该 API 标记为已弃用,并指明它是在哪个具体的 DataFusion 版本中被弃用的
  • 简明地说明首选的 API,以帮助用户完成迁移

弃用版本指的是引入该弃用的下一个版本。例如,如果 Cargo.toml 中列出的当前版本是 43.0.0,那么下一个版本就是 44.0.0。

要将 API 标记为已弃用,请使用 #[deprecated(since = "...", note = "...")] 属性。

例如:

#[deprecated(since = "41.0.0", note = "Use new API instead")]
pub fn api_to_deprecated(a: usize, b: usize) {}

已弃用的方法将在代码库中保留 6 个大版本或 6 个月(以较长者为准),以便为用户提供充足的时间完成迁移。

请参阅 DataFusion 版本列表,提前规划 API 迁移。

评论

登录后参与评论

正在加载评论…