为每个API版本使用单独的目录

Amr*_*Amr 10 php api laravel api-versioning

我打算用Laravel框架创建一个API.并有可能成为API的多个版本,如果我继续发展它,如:v1,v2,v3,等等.

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

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

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

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


编辑:

为什么我会想到这种方法?

因为我想到了以下几点:

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

Par*_*ras 7

我认为这是一个坏主意 - 大量的重复代码,重复维护,绝对没有优势.

构建当前用例

首先:

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

很多CTO /技术架构师都会因为有时候对未来的思考太多而弄错了.如果我的音量增加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等工具轻松升级


San*_*ari 6

我的建议:

使用子域名

让你的api可以在网址上找到:mobile.laravel.app或者api.laravel.app.

这使您可以灵活地为api使用不同的服务器(因此使用不同的框架),或者继续为您的应用程序使用相同的laravel应用程序.您可以在laravel中使用子域路由来使用同一个应用程序处理多个域.

您的版本控制策略

一个通常将版本no.s of api保留为{major}.{minor}(内联语义版本控制).未成年人向后兼容.

例如

api.laravel.app

要么

api.laravel.app/v1/... (特别是如果它指向不同的IP地址).

您可以再次根据您正在进行的更改选择指向不同的服务器或文件夹或不同的控制器.

使用Laravel进行版本化API

我工作的大多数项目都在Laravel上,这就是我们在Laravel中处理版本控制的方式.

Apis是在以下子域收到的: api.laravel.app/v2/...

API已版本化,可在mobile.laravel.app或中获得api.laravel.app

处理这些API的控制器分组在文件夹中 api.laravel.app

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

我仍然建议在接下来的3-6个月内制定"路线图"和com模板功能以及版本号.


shy*_*.me 5

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

为什么要复制整个框架,没有必要这样做.这样做会有相同文件的许多版本,最终会出现重复的代码.如果您在所有版本中发现常见方法的错误,您必须在所有版本中进行更改.

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

您的所有3点与组织API的方式无关,只要您更改语言或框架,就必须重写它,除非它只是版本更改.

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

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

方法1:

相反,我更喜欢最佳实践是版本控制你的API在不同的分支或标记它们像laravel本身正在做.(见下图)

在此输入图像描述

好处 :

  • 轻松切换API
  • IDE很舒服,因为没有相同的名称文件可供搜索和编辑,因此您不会错误地编辑不同的版本.
  • 任何时候您都可以更新任何版本.
  • 查看更改历史记录
  • 在使用此方法在不同文件夹副本上进行开发时,您将体验到更多.

方法2:

我能看到的另一个选项是我将API与版本特定的前缀分组.如果您希望一次运行所有版本并使用单一副本.但这不太值得推荐.

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

请参阅下面的代码段:

/* 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');
});
Run Code Online (Sandbox Code Playgroud)

好处 :

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

注意:两者都是特定于情境的方法,如果新版本中的更改少于5或10,我会选择方法2.但这是个别特定选择.


小智 0

是的,你是对的。这是一个非常糟糕的主意。挑战在于,即使想到一个优势,但实际上根本没有。

我建议您坚持一次安装,并且可以使用Dingo API。该软件包将为您提供一组开箱即用的工具和标准 API 实践。v1包括v2您想要的版本控制。

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

祝你好运。