当前位置: 首页 > 后端技术 > Node.js

为什么喜欢NestJS

时间:2023-04-04 00:35:35 Node.js

欢迎关注我的公众号瑞谈,获取我的最新文章:1.前言做过JavaEE开发的朋友应该对Spring框架不陌生。其全面的功能和出色的设计是其广受欢迎的原因。通过控制反转、依赖注入、面向切面编程等设计理念的灵活运用,极大地规范了大型应用的架构,降低了模块之间的耦合度,从而提高了应用的开发效率。在NodeJS的世界里,还有一个完全借鉴了Spring设计思想的框架。它在github上拥有近20,000个star,在npm上的每周下载量超过110,000。本文要介绍的就是NestJS。2、与其他框架的比较市面上的NodeJS服务端框架有很多,比如K??oa、Express、EggJS、Midway等,它们都很强大,生态也很好。插件非常丰富。为什么需要Nest?如果它是一个简单的应用程序,那么使用什么框架并不重要。一个框架用100行代码实现,另一个框架用80行代码实现。没有太大区别。但是到了企业级应用,每分钟都有几万行代码,代码的组织结构就变得非常重要。如果代码拆分不合理,一个JS文件就会有几千行代码,后期的维护成本会非常高。考虑到一个复杂项目的参与者很多,如果没有规范来约束,每个人写的代码风格差异很大,很难协同。上面提到的这些框架,要么对项目代码的结构没有约束,要么约束比较弱,或者显得别扭。相比之下,Nest的实现非常简单易用。具体细节将在下面描述。Nest还通过依赖注入实现了控制反转。只要你在模块中声明依赖,Nest就会在启动时创建依赖,然后自动注入到相应的地方。依赖注入最大的作用就是代码解耦。根据不同的情况,依赖对象可以有多种实现。比如在单元测试时,可以在不改变业务代码的情况下,将依赖对象替换为Mock数据。Nest也践行了面向切面编程的思想。除了Middleware,还有ExceptionFilter、Pipes、Guards、Interceptors等几个预定义的方面,可以专注于异常处理、数据验证、权限验证、逻辑扩展等功能。Nest自带了一些常用的切面功能,比如数据校验,也可以通过继承来扩展。这些预定义的方面是代码架构的一部分,按照这些约定组织代码将大大降低未来的维护成本。类型系统是后端开发中非常重要的一部分。Nest是一个使用TypeScript实现的框架,所以它原生支持TypeScript,同时也使用了大量的注解。熟悉Spring的朋友会觉得很亲切。另外,Nest是基于Express实现的,需要时可以获取request、response等底层对象。3.实战下面的讲解将基于一个简单的CRUDAPI服务器。完整的项目代码在这里,这里就不一步步介绍编写过程了。ModularNest以模块的形式组织项目,其中可以声明Controller、Provider、Import和Export。打开app.module.ts,内容如下:@Module({imports:[CatsModule,MongooseModule.forRoot('mongodb://localhost/nest')],controllers:[AppController],providers:[AppService],})exportclassAppModule{}可以看到项目的根模块AppModule导入了项目中的另一个模块CatsModule和外部依赖MongooseModule。另外声明了模块内部的Controller和Provider。我们一般说的Service就是Provider的一种。Module、Controller和Provider的关系如下图所示:Controller和Provider都注册在Module中,容器会将Provider注入到Controller中,Modules可以相互引用(Import)。像ES6的模块化,导入后只能使用别人导出的内容。注意让我们再看看cats.controller.ts。@Controller('cats')exportclassCatsController{constructor(privatereadonlycatsService:CatsService){}@Get(':name')asyncfindOne(@Param('name')name:string):Promise{返回this.catsService.findOne(名字);}@Get()asyncfindAll():Promise{returnthis.catsService.findAll();}@Post()@HttpCode(201)@Header('Cache-Control','none')asynccreate(@Body(newValidationPipe())createCatDto:CreateCatDto,):Promise{返回这个。catsService.create(createCatDto);这个文件有很多注解,这是Nest区别于其他NodeJS框架的地方,很像Spring。很多注解的含义也和Spring一致,比如这里的@Controller、@Get、@Post就是用来声明路由和http请求类型的。@Get(':name')是获取url的参数,@Param('name')是获取请求体的参数。@Body(newValidationPipe())createCatDto:CreateCatDto这行代码做了很多事情,首先取出请求体,然后验证数据类型是否合规,然后将请求体转换为DTO对象,以供后续使用.DTO的定义如下,同样通过注解定义校验逻辑:exportclassCreateCatDto{@IsString()readonlyname:string;@IsNumber()只读年龄:数字;@IsString()readonlybreed:string;}上面提到的切面ValidationPipe是内置的Pipe切面,用于验证参数类型。其他方面和请求处理的顺序如下图所示:这里的中间件是Express原生的,其他方面的用法可以在官方文档中找到,这里就不做介绍了。在连接数据库的例子中,使用了mongoose来连接和操作本地的MongoDB数据库。为了更方便的使用,Nest提供了@nestjs/mongoose包,对mongoose进行了包装,使其更符合Nest的使用风格。操作数据库的步骤如下:在app.module中定义连接的数据库:MongooseModule.forRoot('mongodb://localhost/nest')在cat.schema中定义Schemacats.module声明依赖Model:MongooseModule.forFeature([{name:'Cat',schema:CatSchema}])cats.serviceinjectdependencyModel:constructor(@InjectModel('Cat')privatereadonlycatModel:Model){}在cats.service中使用模型:this.catModel.findOne({name}).exec()4.总结本文着重阐述了Nest的设计思想,比较了它与其他框架的异同,并结合实例详细说明了具体的用法。写这篇文章的目的是为框架选择者提供快速参考,也为对Nest感兴趣的人提供感性认识。如果您想了解更多Nest的使用方法,请查看官方文档。附言腾讯云招聘前端工程师,欢迎加我微信: