当前位置: 首页 > 科技观察

Node.js 的 Web 框架的 3 个层次,理清了就不迷茫

时间:2023-03-12 09:55:00 科技观察

Node.jsweb框架的三个层次,弄清楚就不会混淆了是web框架的基础。但是http和https的api过于简单,使用起来也比较繁琐,所以一般会使用express、koa、fastify,通过一层框架来简化封装。但是express框架不提供代码结构限制,不适合模块多且复杂的企业级应用。这种情况下,就必须使用实现MVC的eggjs、nestjs等企业级web框架。这些是Web框架的三个级别。理清了它们的关系和适用场景,学习起来就不会一头雾水了。我们分别来看一下:http和httpshttp是基于TCP的。它们解析TCP传递过来的http协议数据,传递给handler进行处理。处理程序完成处理后,它会返回一个http响应。这就是http模块的作用。consthttp=require('http');constserver=http.createServer((req,res)=>{res.writeHead(200,{'Content-Type':'text/plain'});res.end('好的');});server.listen(8080,'127.0.0.1');http模块虽然可以处理请求和响应,但是它提供的API过于原始:比如获取请求参数,使用url模块解析一次consthttp=require('http');consturl=require('url');http.createServer(function(req,res){constqueryObject=url.parse(req.url,true).query;console.log(queryObject);res.writeHead(200,{'Content-Type':'text/html'});res.end('xxx');}).listen(8080);比如returnresponse只能返回一个buffer或者stringwithwriteorend,如果要返回json、文件下载、html查看等,就得自己实现了。而且get、post、put、delete等请求类型要自己判断。if(req.method==='get'){//...}elseif(req.method==='post'){//...}//...因为这些痛点,所以general我们不会直接使用http模块,而是封装了一层的express、koa、fastify等web框架。express、koa、fastify等框架解决了刚才的痛点问题:提供路由机制,无需手动判断method和pathapp.get('/list',function(req,res){//...})app.post('/save',function(req,res){//...})提供更好的请求和响应api:如req.params获取请求参数app.get('/user/:id',function(req,res){res.send('user'+req.params.id)})res.download返回下载的响应res.download('/report-12345.pdf')res.render返回由模板引擎呈现的html应用程序。render('xxx-template',{name:'guang'},function(err,html){//...})提供了一种中间件机制,用于复用一些Logic:比如文件上传中间件app.use(fileUpload({useTempFiles:true,tempFileDir:'/tmp/'}));提供了这么多方便的功能,确实比http模块好用多了。但是expressweb框架也有一个问题,就是没有提供组织代码的模式。当模块太多的时候,代码很容易乱,因为它只是按照洋葱的顺序调用中间件,没有模块和MVC的划分。express类框架可以做一些小服务,企业级应用必须使用nestjs、eggjs等MVC框架。Nestjs、eggjs、midwayjs、daruk等nestjs框架实现了MVC模式,代码有明显的Controller、Service、Model、View划分:import{Body,Controller,Delete,Get,Param,Post}from'@nestjs/common';import{CreateUserDto}from'./dto/create-user.dto';import{User}from'./user.entity';import{UsersService}from'./users.service';@Controller('用户')exportclassUsersController{constructor(privatereadonlyusersService:UsersService){}@Post()create(@Body()createUserDto:CreateUserDto):Promise{returnthis.usersService.create(createUserDto);}@Get()findAll():Promise{returnthis.usersService.findAll();}@Get(':id')findOne(@Param('id')id:string):Promise{returnthis.usersService.findOne(id);}@Delete(':id')remove(@Param('id')id:string):Promise{returnthis.usersService.remove(id);}}nestjs用于javaSpring实现IOC、AOP等模式,模块之间的耦合度很低。即使是复杂的项目也可以通过Module、Controller、Service等很好的组织起来。代码的组织方式相比express更上一层楼。nestjs底层是express、fastify等web框架,底层实现可以灵活切换。可以看出,除了丰富的API,像nestjs、eggjs这样的企业级框架,都提供了代码组织规范。复杂的业务逻辑可以通过模块、控制器和服务等概念很好地组织起来。综上所述,web框架都是基于http和https模块,但是其提供的api过于原始,使用起来比较麻烦,所以我们一般会使用express、koa等框架来简化,提供中间件机制来复用逻辑,提供有更多的请求和响应API,但是它们没有组织复杂代码的能力。对于复杂的企业级应用,仍然使用nestjs、eggjs等MVC框架。它们的底层都是express和koa,但是它们提供了Module,Controller,Service等概念,可以很好的组织复杂的代码。有必要弄清楚为什么会有这三个层次,每个层次适用于什么场景,这样我们才能更好的把握它们,而不是在技术的选择上混淆。