【问题标题】:Best practices for API backwards compatibilityAPI 向后兼容性的最佳实践
【发布时间】:2012-05-23 08:16:26
【问题描述】:

我正在开发一个与 JSON API 通信的 iPhone/iPad/Android 应用程序。

该应用版本的第一个版本已完成,现在正在进行其他开发阶段。在其他阶段,应用程序需要与新版本的 API 集成,并允许用户访问其他功能,例如新屏幕或现有屏幕中的修改行为。但是,该应用确实需要使用以前版本的 API。

解决此类要求的最佳做法是什么? 我可以对整个代码进行检查:

if (APIVersion == 1) {

} else if (APIVersion == 2) {

} else if (APIVersion == ....) {

}...

但我担心这种方法的可扩展性。 想到了工厂方法,但我不确定这会让我走多远。

谢谢, 标记

【问题讨论】:

    标签: api backwards-compatibility


    【解决方案1】:

    发布新的 API 版本是非常罕见的事情。通常,您只需添加新的可选参数或新方法即可实现向后兼容。例如,如果你有一个名为search的方法,但现在你对它的工作方式不满意,你可以通过各种方式来处理它:

    • 如果更改很简单,您可以添加一个新的 mode 参数,默认为 mode1(因此它是向后兼容的)。如果用户提供mode2,您会按照您自己提出的正确if 条件检测到它。 (另外,通常你可以想出一个比“mode”更好的名字。)

    • 如果改动很大,你可以添加一个新的search2服务,它使用新的接口。然后将 search 方法标记为已弃用(但仍然有效且向后兼容)。通常当你这样做时,你可以重构你的代码,几乎所有的逻辑都在 search2 方法内,而你的旧 search 方法在内部调用 search2修改参数(并适当地重新格式化结果)。如果您正确执行此操作,您将不再需要更改 search 方法。当您更改表格等时 - 您只需修改 search2

    我的意思是,避免发布 API 的N+1-st 版本。如此大的版本意味着您的方法所有的重大变化,而不仅仅是一个。许多主要的 API 从未发布其 API 的第 2 版,它们仍然使用第 1 版,只是稍微修改了其中的一部分,如上例所示。

    如果您绝对确定要发布您的 API 的N+1-st 版本,请为您的所有方法创建新的入口点。如果您有一个名为 services 的文件夹,请创建一个名为 services-v2 的新文件夹。重构您的services 代码,使其充分利用services-v2。如果您认为这太过分了,那么我认为您还不需要 N+1-st 版本的 API。

    顺便说一句,不要将集中式 API(如 Google 地图)与分布式 API(如 Android)混淆。 Android 一直在发布新的 API 版本,因为有数十亿台 Android 服务器(每台 Android 设备就是一台),而且它们都不能简单地由 Google 远程升级。 下一个版本的 Android 仍然向后兼容上一个版本,增加数字只是为了表示新功能。您仍然可以在 Android 7.0 上运行为 Android 3.0 构建的应用程序(用户可能会收到一些额外的警告,但应用程序会运行)。 Android 应用程序开发人员使用这些数字来描述他们的应用程序的“最低要求”。 然而,集中式 API 通常会增加其版本号以表明重大的向后不兼容更改

    【讨论】:

    • 谢谢。我提出了第一个要点建议。更改相当小,因此我设法执行 API 版本条件检查,并使用不同的可选参数扩展方法,或者在某些情况下为每个 API 版本创建新方法。 API 版本超出了我的控制范围,因为它是一个客户端 API。
    • 这是一个非常好的答案,我希望我也能得到一些链接和指针。
    【解决方案2】:

    我猜你已经有了关注点分离。我的意思是,为您的应用获取数据只能通过模型​​完成(例如)。

    所以你只需要改变模型。

    我的建议是只有一个入口点:“路由器”文件。此文件检查所需的 API 版本,并加载正确的文件。这样,您可以为每个 API 获得不同的文件。 “路由器”文件不会很大,每个新的 API 版本都有自己的文件,所以你不会混合所有内容。

    例如在“路由器”文件中:

    function dispatch() {
        switch (APIVersion) {
        case 1:
            use('file.1.ext');
            break;
        case 2:
            use('file.2.ext');
            break;
        case 3:
            use('file.3.ext');
            break;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-28
      • 2017-11-18
      • 1970-01-01
      • 2016-03-23
      相关资源
      最近更新 更多