api 版本控制过程中如何搭建文件结构?

目标:有两个版本的api, v1和v2,希望在使用同一个服务器的情况下,两个版本的api能同时运行。
项目结构: router/controller/service/model文件夹
解决方案:
1.v2可以完全复制粘贴v1的所有文件夹,基于v1进行修改,最终得出如下文件结构

--src
    --v1
        --v1 route
        --v1 controller
        --v1 service
    --v2
        --v2 route
        --v2 controller
        --v2 service
    --db
    --config

这种方法的情况下会有大量的重复代码,感觉不是很好。但是这个是最直观的解决方案。很笨但是有效。
2.v2可以继承v1需要修改的部分文件,并覆盖其中的一部分函数

--src
    --router
    --controller
        --user
        --user_v2 extends user //导出这个新的controller给router v2
    --service
        --user
        --user_v2

这种方式可以最小程度的重复代码,不过比如v2的时候我们改了user controller,v3的时候我们改了movie controller,最后改来改去就改乱了。而且router v2里面的大部分controller还是引用的v1 controller,只有user是新版本的controller.容易搞乱套。

所以,真心求教大佬们,如何设置文件结构,才能极其优雅的管理不同版本的api,可以有清晰的工程结构,同时,可以有最少的代码重复。可以提供与以上两种解决方式不同的任何方案。

网上真的真的搜不到好的解决方案,我想着,这互联网发展了30年了,咋这点东西都搜不到,很受打击。真心求教最佳实践。

阅读 2k
3 个回答

结合了你说的那两种,推荐你用这个项目结构:

src
|-- api
|   |-- v1
|   |   |-- controllers
|   |   |   |-- user.js
|   |   |   |-- movie.js
|   |   |-- routes
|   |       |-- index.js
|   |-- v2
|       |-- controllers
|       |   |-- user.js (extends v1 user controller and overrides necessary methods)
|       |   |-- movie.js (extends v1 movie controller and overrides necessary methods)
|       |-- routes
|           |-- index.js
|-- services
|   |-- user.js
|   |-- movie.js
|-- models
|   |-- user.js
|   |-- movie.js
|-- config
|-- db

之前也想过,其实你上面就已经提到了,直接拷贝代码来实现 v1/v2/v3 这种方式,或者使用继承,覆盖方法的方式。

前者会造成代码冗余,这是毋庸置疑的的。

后者有好也有坏,假设 v2 继承自 v1,v3继承自 v2,那将来 v1 发生大变化时,势必就会影响到 v2/v3。亦或者,v1 引入一个 bug 后,极有可能影响到 v2/v3。

但是对于前者,一般不怎么会出现这种情况,因为做到了代码隔离(要考虑自动加载和命名空间的问题)。


在刚刚,把这个问题丢给 ChatGPT 以后,他给出了一个之前我未曾想到过的方案,就是把代码交给 VCS,即版本控制系统,比如 Git,由其中的分支来实现。分别创建 v1/v2/v3 分支,类似于拷贝代码,但是代码更加规整了。

我觉得这样算是优解,只不过在部署时需要部署多份了,但是这样还可以降低运行的风险,如果其中一个版本出现问题,不至于影响到其他版本。

如果你希望在生产环境的统一程序下必须通过文件的方式组织管理不同版本的代码逻辑,那么建立以版本划分的文件夹是一个好的实践方式。
对于完全重复的两份代码,可以通过文件系统进行关联。例如,你可以通过创建硬链接的形式对文件进行“拷贝”。
对于重复的代码片段,你可以建立公共的库文件,并通过库共享你的代码片段。


如果你仅希望在编码阶段对代码进行版本管理,你可以选择任意一种VCS。一个最佳实践是,你可以为你的每个版本打上版本标签,并为大版本建立单独的分支,以便在未来为一些历史代码发布严重漏洞补丁。
基于此模式的程序,一般通过构建与源码版本绑定的镜像进行发布。通过容器编排,你可以轻松地将流量分流进入不同版本镜像的容器。

推荐问题
logo
Microsoft
子站问答
访问
宣传栏