【问题标题】:Using separate directory for each version of the API为每个版本的 API 使用单独的目录
【发布时间】:2018-06-07 14:41:11
【问题描述】:

我打算用 Laravel 框架创建一个 API。如果我继续开发,可能会有多个版本的 API,例如:v1v2v3 等等。

我不是只有一个 Laravel 框架副本并通过为每个版本创建不同的目录来对其中的 API 进行版本控制,而是考虑为每个版本的 API 创建一个完全独立的 Laravel 框架副本。

例如,假设这是 API 的 URL:website.com/api,我正在考虑在 api 目录中创建一个名为 v1 的目录,并将 Laravel 的完整副本放入其中。稍后当我需要创建新版本的 API 时,我会在 v1 旁边创建另一个名为 v2 的新目录,并在其中放置一个新的完整且单独的 Laravel 副本,依此类推。

这样,当我想访问 API 的版本 1 时,我将访问这个 URL:website.com/api/v1,当我想访问版本 2 时,我将访问 website.com/api/v2

我的问题:这是个坏主意吗?这种方法有什么缺点?


编辑:

我为什么想到这种方法?

因为我想到了以下几点:

  • 如果有一天我想用 Laravel 以外的 PHP 框架创建一个新版本的 API。
  • 如果有一天我想用 PHP 以外的编程语言创建新版本的 API。
  • 如果有一天我想升级到较新版本的 Laravel,并且该版本对最初创建 API 的版本有重大更改,该怎么办。

【问题讨论】:

  • 我找不到一个优势而不是劣势,你为什么要这个?
  • 你不需要它(首字母缩略词:YAGNI)是极限编程 (XP) 的一项原则,它规定程序员在认为有必要之前不应添加功能。 en.wikipedia.org/wiki/You_aren%27t_gonna_need_it

标签: php laravel api api-versioning


【解决方案1】:

我认为这是一个坏主意 - 大量重复代码、重复维护并且绝对没有优势。

为当前用例构建

首先:

您需要构建技术来满足当前的用例(并且非常 不久的将来)

很多首席技术官/技术架构师有时会因为对未来考虑太多而弄错了。如果我的音量增加 1000 倍怎么办?我应该使用大数据堆栈吗?不,当然不会,除非您预计它会在未来 3 个月内发生!

你的方法的缺点

  1. 代码重复:你最终会重复很多代码——你的 Eloquent 模型、业务逻辑、身份验证、中间件等。
  2. 维护和其他开销:根据您的技术堆栈,维护也会重复。例如想象一下在多个应用程序上运行 Artisan 命令以进行简单的配置缓存刷新。更不用说对依赖项、硬件资源等的单独升级了。

优势

您的方法没有明显的优势。让我们看一下促使您采用这种架构的具体问题:

  1. 如果有一天我想用 Laravel 以外的 PHP 框架创建新版本的 API,该怎么办?

假设您当前有 3 个版本,并且您想在不同的框架上创建版本 #4。好吧,你仍然可以在单个 Laravel 应用程序上拥有前 3 个版本,在不同的应用程序/代码库上拥有第 4 个版本。如果您已经有 3 个现有版本,则没有理由将它们作为单独的 Laravel 应用程序

  1. 如果有一天我想用 PHP 以外的编程语言创建新版本的 API。

嗯,这同样适用于这里。如果出现这种情况,您始终可以为不同语言的未来版本提供不同的应用程序

  1. 如果有一天我想升级到更新版本的 Laravel,并且该版本对最初创建 API 的版本有重大更改,该怎么办。

次要版本在 Laravel 中向后兼容。所以,如果你从 Laravel 5.1 升级到 5.5,应该没有重大变化。对于主要版本,您可以选择不同的应用程序(如果需要),但实际上,即使是主要版本升级也可能不是挑战。当然,你也可以使用Laravel Shift等工具,让你轻松升级

【讨论】:

    【解决方案2】:

    我的建议:

    使用子域

    让您的 api 在以下网址可用:mobile.laravel.appapi.laravel.app

    这使您可以灵活地为您的 api 使用不同的服务器(因此也使用不同的框架),或者继续为您的应用程序使用相同的 laravel 应用程序。你可以在 laravel 中使用 sub-domain routing 来处理使用同一个应用程序的多个域。

    您的版本控制策略

    通常将 api 的版本号保留为 {major}.{minor}(与语义版本控制内联)。未成年人向后兼容。

    例如

    api.laravel.com/v1.2/...
    

    v1.api.laravel.com/...
    

    (尤其是如果它指向不同的 ip 地址)。

    同样,您可以根据所做的更改选择指向不同的服务器或文件夹或不同的控制器。

    将 Laravel 用于版本化 API

    我从事的大部分项目都在 Laravel 上,这就是我们在 Laravel 中处理版本控制的方式。

    API 在子域中接收,例如:api.laravel.app

    API 是版本化的,可在api.laravel.app/v1/...api.laravel.app/v2/... 获得

    处理这些 API 的控制器被分组到文件夹中

    App
    |-Http
      |-Controllers
         |-API
            |-v1
               - controllers for v1
            |-v2
               - controllers for v2
    

    如果在未来某个日期,您想更改服务器、平台或使用不同版本的 laravel 等 - 您可以通过不同的子域进行处理。

    我仍然建议在接下来的 3-6 个月内一次制定“路线图”和 com 模板功能和版本号。

    【讨论】:

      【解决方案3】:

      我正在考虑创建一个完全独立的 Laravel 副本 每个 API 版本的框架。

      为什么要复制整个框架,这样做没有意义。这样一来,您将拥有同一文件的多个版本,并且最终会出现重复的代码。如果您在所有方法中发现了共同方法中的错误怎么办 版本,您必须在所有版本中更改它。

      • 如果有一天我想用 Laravel 以外的 PHP 框架创建一个新版本的 API。
      • 如果有一天我想用 PHP 以外的编程语言创建新版本的 API。
      • 如果有一天我想升级到更新版本的 Laravel 并且该版本对 API 的版本进行了重大更改,该怎么办? 最初创建于。

      您的所有 3 点都与您如何组织 API 无关,一旦您更改语言或框架,您将不得不重写它,除非它只是版本更改。

      基于预测语言更改或框架来制作 API 结构是没有意义的。 Ebay、Paypal、Facebook、Google 等都改变了他们选择的语言并在某个时间点重写了他们的代码库。他们没有预见到这种变化,并据此制作了他们的系统。

      所以我可以看到很多缺点。

      方法一:

      我更喜欢最好的做法是在不同的分支中控制您的 API 或标记它们,就像 laravel 本身所做的那样。 (见下图)

      优点:

      • 在 API 之间轻松切换
      • 兼容IDE,不会搜索和编辑同名文件,不会误编辑不同的版本。
      • 您可以随时更新任何版本。
      • 查看更改历史记录
      • 在使用这种方法在不同文件夹副本上进行开发时,您会体验到更多。

      方法二:

      我可以看到并且已经完成的另一个选项是将您的 API 与特定于版本的前缀进行分组。如果您希望所有版本一次运行一个副本。但这不太推荐。

      根据版本更改方法名称或控制器名称,或将它们放在特定于版本的命名空间中

      见下面的sn-p:

      /* Version v1  */
      Route::prefix('v1')->group(function () {
          Route::get('users','UsersController@index');
          Route::get('foobars','FooController@bar');
      });
      
      /* Version v2  */
      Route::prefix('v2')->group(function () {
          Route::get('users','UsersController@index'); 
          Route::get('foobars','FooController@bar');
      });
      

      优点:

      • 在单个项目中一次运行所有版本,
      • 组织良好,路由,
      • 控制器、模型的命名空间明智版本。 (您可以保留通用控制器,并在方法名称前加上版本号,以减少复制粘贴工作)。
      • 无分支切换

      注意:两者都是针对特定情况的方法,如果新版本的更改少于 5 或​​ 10 处,我会选择方法 2。不过这是个人特定的选择。

      【讨论】:

        【解决方案4】:

        是的,你是对的。这是一个非常糟糕的主意。挑战甚至是想出一个优势,但没有。

        我会建议你坚持一个安装,你可以使用 Dingo API 。一个可以为您提供开箱即用的工具和标准 API 实践的包。包括v1v2 等版本控制。

        这将提高您的代码可重用性以及许多其他有助于您构建标准 API 的东西。

        祝你好运。

        【讨论】:

        • 一个好处是可以设计系统以回退此类/方法不在 V2 中,因此以这种方式加载 V1 版本,您不会在各个版本之间有重复的代码。
        【解决方案5】:

        这不完全是这个问题的答案,既然你说你“计划”使用 laravel,我想推荐另一个支持 REST API 版本的平台。

        https://apigility.org/

        Apigility,使用zendframework作为基础,如果你有兴趣使用其他框架,我推荐它。

        【讨论】:

          【解决方案6】:

          如果我理解正确,那么您是在“混合”您的开发和部署架构。

          我在您的生产环境中没有看到任何问题,您的 API 基于 url 路径(如您所建议的那样)甚至是子域的多个版本。

          您的控制版本(git、svn 等)应该照顾您可能拥有的每个 API 版本。如果你想开发一个新版本:创建一个新分支,开发并测试它,然后创建一个标签。

          然后,当您部署应用程序本身时,您会关心如何通过特定路径或域访问它。

          【讨论】:

            猜你喜欢
            • 2018-10-12
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-04-23
            • 1970-01-01
            • 2011-11-16
            • 2011-07-09
            • 1970-01-01
            相关资源
            最近更新 更多