nestjs-版本控制

前言

nestjs 开发迭代版本时,也会碰到其他后端碰到的问题,那就是版本迭代,有时候可能会兼容一下就行了,有时会进行破坏性更新,那么我们可能要被迫分开接口来进行我们的操作,常见的就是添加版本参数判断操作了

添加版本参数主要有两种手段,一种加入到 uri 中,一种 header 中(当然还有更简简单粗暴的手段,直接换一个url,后面介绍)

其中加入到 uri 中,就是我们的接口url中要添加拼接一个版本号,挺常见;另一种就是放到 header 中,这个更是很常见,我们的设备类型(android、ios、web、小程序类型一般都是放到这里吧),因此 header 方案也是比较推荐

参考

另外也会谈谈个人的小见解

设置版本控制

URI 类型

将版本设置到 uri 中,也是比较推荐的,需要注意的是,版本参数放到我们的 api 前缀 后面,如果没有前缀,则直接加到域名后面就行了

js 复制代码
app.enableVersioning({
  type: VersioningType.URI,
});

//实际访问的url在 api 前缀之后加上版本号 v1(v+版本号)
http://localhost:4000/api/v1/order/create
//如果是设置了中立,就不需要加入版本号了
http://localhost:4000/api/order/create

Header 类型

将版本设置到 header 中,也是比较推荐的

js 复制代码
app.enableVersioning({
    type: VersioningType.HEADER,
    header: 'Api-Version', //自己起名字,别重复就行
});

只需要在请求的header中加入  Api-Version 1 即可,直接传入版本号即可

媒体类型 Accpet

设置到媒体类型 Accpet 中,不是很常见

js 复制代码
app.enableVersioning({
  type: VersioningType.MEDIA_TYPE,
  key: 'v=',
});

这个传递时需要设置 Accept,这个参数会默认设置一下可以这么用,用的比较少
Accept: application/json;v=2

这个使用一个案例吧,如需哦啊所示,后面拼上 v=版本号

应用版本号到路由

可以直接设置版本号到控制器,也可以设置版本号到指定路由器,这样指定版本的就都可以访问了,可以设置支持一个或多个版本,

可以根据版本分成两个处理方法,毕竟有些版本确实存在破坏性修改,但是老的也不能抛弃;也有的直接连续支持好几个版本,直接一次多个

当然没有版本疑虑的可以直接不声明版本类型,这样都可以访问,在需要时在分离,只需要加上版本号兼容即可

js 复制代码
@Version('1')
@Controller('version')
// @Controller({
//     version: VERSION_NEUTRAL, //中立,在没有版本控制的路由上不需要拼接url了(主要针对于url版本)
// })
export class VersionController {
    constructor(private readonly versionService: VersionService) {}

    @Version('1')
    @Get('test')
    test1() {
        return '测试版本1';
    }

    @Version('2')
    @Get('test')
    test2() {
        return '测试版本2';
    }

    @Version(['1', '2'])
    @Get('test2')
    test3() {
        return '测试版本1-2';
    }
}

问题

上面的方便是方便,可是问题也是很多,例如:

我们的 uri 版本发现 swagger 支持不太理想,复制了url不能直接用,还要手动改,很麻烦,且会看不到多个版本不同的参数信息

headers 需要传递隐藏的版本信息,编写swagger文档也得额外标记,并且接口也要经常传递版本信息,无论是使用 swagger 还是前端手动传递都是很不方便

因此这个默认的版本,除非对 nestjs 依赖过强,否则个人是很不推荐的,包括上面三种方式

结论:上面三种都很不好用,直接抛弃最好

个人以前曾经看过一些其他语言的接口写的接口,发现了一个很综合且很好用的方案,因为发现,当综合思考过后,最后都会走向同一个岔路口!

无论是使用方便,还是swagger文档看着方便,那毫无疑问就是 url 方案了,只不过跟上面的稍微不一样罢了

新的方案(简单易懂-力推)

我们在版本控制时,最常见的问题就是,新老版本的使用问题,对于那些版本没变化的,不用管就行,因此我们直接使用最原始的方案即可,手动处理

我们平时编写时,无需考虑版本问题,也不需要要额外配置,就正常开发

当我们需要新的版本时,如果老版本可以直接删了这种的,直接重写就好

我们可能对于老版本有所破坏,也就是新增加、搞懂了一些功能,但同时老功能还需要保持原样的,这样的问题比较多

此时我们可以不动老接口,直接添加一个新的接口新接口前面加上前缀 v1(v+版本号)

js 复制代码
//我们老接口
@Get('test2')
Test2() {
    return '版本v1版本';
}

//新接口
@Get('v2/test2')
superTest2() {
    return '强化版本v2';
}

//如果全改了,那么直接这样即可
@Controller('version/v2')
export class VersionController {}

看到上面我们可能就恍然大悟,就这么简单就区分开了,不仅使用上没有什么难度,并且接口文档也无需太大改变,只需要新版本的接口url添加一个版本信息即可

对于需要增加版本,可以分接口,也可以不分开,老的代码是可以提取出来的是吧,service 之间也可以通信是吧,这不代码也能更好得分离出来

对于在新版本之上,在增加新的版本,那么我们只需要老代码保持原样就行了,继续新增一个接口即可,老接口 v1 变成 v2 即可,可能有些接口更新到了v8版本,有些才 v2,不用管,没有升级的,就以最新一次更新的版本号为基准使用即可(也就是保持原样,根本不需要动即可)

就这样我们的版本控制方案了,简单粗暴(前面有提到的就是这种哈)

最后

我们编写代码时,如果有些不方便,不妨停下来思考一下,并不是说一些社区推荐给我们的就是最好的,或者最适合我们的,如果能一次性开发出终极版本,那么现实中也不会存在那么多版本的应用了

总结:就是在使用一个方案时,要看到他的优缺点,而不是直接就上到自己的应用中,可以斟酌一下,有不足如果能改善,也算提升一下自己了哈

最后,思考和学习能够让自己收获更多,一起进步吧

相关推荐
kongxx7 天前
NestJS中使用Guard实现路由保护
nestjs
白雾茫茫丶8 天前
Nest.js 实战 (十二):优雅地使用事件发布/订阅模块 Event Emitter
nestjs·nest.js·发布订阅·event emitter
lph65821 个月前
比起上传资源更应该懂得如何资源回收
node.js·nestjs
gsls2008081 个月前
将nestjs项目迁移到阿里云函数
阿里云·云计算·nestjs·云函数
d3126975101 个月前
在Nestjs使用mysql和typeorm
mysql·express·nestjs·typeorm
潇洒哥gg2 个月前
重生之我在NestJS中使用jwt鉴权
前端·javascript·nestjs
huangkaihao2 个月前
【NestJS学习笔记】 之 自定义装饰器
前端·node.js·nestjs
鹿鹿鹿鹿isNotDefined2 个月前
Nest 源码解析:依赖注入是怎么实现的?
nestjs
剪刀石头布啊2 个月前
nestjs-自定义装饰器
nestjs