帶你理清Node.js 的Web框架的3個層次

roc_guo發表於2021-10-17

eb 框架指的是處理 http、https 的服務端框架,Node.js 提供了 http、https 模組用於處理協議資料,這是 web 框架的基礎。

但是 http、https 的 api 過於簡單,用起來比較麻煩,所以一般會用 express、koa、fastify 這種封裝了一層的框架來簡化。

但 express 類的框架不提供程式碼架構方面的限制,所以對於模組比較多比較複雜的企業級應用來說並不適合,這時就要用實現了 MVC 的 eggjs、nestjs 這類企業級 web 框架。

這是 web 框架的 3 個層次,理清了它們的關係和適用場景,再去學習才不會迷茫。

下面我們分別來看一下:

http、https

http 是基於 TCP 的,對 TCP 傳過來的 http 協議資料做 parse,傳給 handler 處理,handler 處理完要返回 http 響應,這是 http 模組做的事情。

const http = require('http'); 
 
const server = http.createServer((req, res) => { 
  res.writeHead(200, { 'Content-Type': 'text/plain' }); 
  res.end('okay'); 
}); 
 
server.listen(8080, '127.0.0.1');

http 模組雖然能處理請求和響應,但是提供的 api 過於原始:

比如獲取請求引數還要用 url 模組 parse 一次

const http = require('http'); 
const url = require('url'); 
 
http.createServer(function (req, res) { 
  const queryObject = url.parse(req.url,true).query; 
  console.log(queryObject); 
 
  res.writeHead(200, {'Content-Type': 'text/html'}); 
  res.end('xxx'); 
}).listen(8080);

比如返回響應只能用 write 或者 end 返回一段 buffer 或 string,想返回 JSON、檔案下載、html 檢視等都要自己實現。
帶你理清Node.js 的Web框架的3個層次帶你理清Node.js 的Web框架的3個層次
而且 get、post、put、delete 等請求型別也要自己做判斷。

if(req.method === 'get') { 
    //... 
} else if (req.method === 'post') { 
    //... 
} 
//...

因為有這些痛點,所以一般我們不會直接用 http 模組,而是用封裝了一層的 express、koa、fastify 這類 web 框架。

express、koa、fastify 等

express 這類框架解決了剛才的那個痛點問題:
提供了路由機制,不用自己手動判斷 method 和 path

app.get('/list', function (req, res) { 
  //... 
}) 
app.post('/save', function(req, res) { 
  //... 
})

提供了更好用的 request 和 response 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
app.render('xxx-template', { name: 'guang' }, function (err, html) { 
  // ... 
})

提供了中介軟體機制,用於複用一些一些邏輯:
比如檔案上傳中介軟體

app.use(fileUpload({ 
    useTempFiles : true, 
    tempFileDir : '/tmp/' 
}));

提供了這麼多方便的功能,確實比 http 模組用起來簡單多了。

但是 express 類的 web 框架也有問題,就是沒有提供組織程式碼的模式,當模組多了程式碼很容易亂掉,因為它只是按照類似洋蔥的順序呼叫中介軟體,沒有模組和 MVC 的劃分。
帶你理清Node.js 的Web框架的3個層次帶你理清Node.js 的Web框架的3個層次
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('users') 
export class UsersController { 
  constructor(private readonly usersService: UsersService) {} 
 
  @Post() 
  create(@Body() createUserDto: CreateUserDto): Promise{ 
    return this.usersService.create(createUserDto); 
  } 
 
  @Get() 
  findAll(): Promise{ 
    return this.usersService.findAll(); 
  } 
 
  @Get(':id') 
  findOne(@Param('id') id: string): Promise{ 
    return this.usersService.findOne(id); 
  } 
 
  @Delete(':id') 
  remove(@Param('id') id: string): Promise{ 
    return this.usersService.remove(id); 
  } 
}

nestjs 是對標 java 的 spring 的,實現了 IOC、AOP 等模式,模組之間耦合度很低,就算再複雜的專案,通過 Module、Controller、Service 等也可以很好的被組織起來,相比 express 來說,組織程式碼方面提升了一個檔次。
帶你理清Node.js 的Web框架的3個層次帶你理清Node.js 的Web框架的3個層次
nestjs 的底層就是 express、fastify 等 web 框架,而且還可以靈活的切換底層實現。

可以看到,nestjs、eggjs 類的企業級框架,除了有豐富的 api 以外,更重要的是提供了程式碼組織的規範,通過 Module、Controller、Service 等概念可以很好的組織複雜的業務邏輯。

總結

web 框架都是基於 http、https 模組,但它提供的 api 過於原始,使用起來比較麻煩,所以我們一般會用 express、koa 這類框架來簡化,它提供了中介軟體機制來複用邏輯,提供了更多的 request、response 的 api,但卻沒有組織複雜程式碼的能力,對於企業級的複雜應用,還是會用 nestjs、eggjs 這類 MVC 框架,它們的底層是 express、koa,但提供了 Module、Controller、Service 等概念,可以很好的組織複雜的程式碼。

要理清楚為什麼會有這三個層次,都各自適合什麼場景,這樣才能更好的掌握它們,在技術選型上才不會迷茫。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69901823/viewspace-2837787/,如需轉載,請註明出處,否則將追究法律責任。

相關文章