參考:
https://docs.nestjs.cn/9/controllers
控制器負責處理傳入的請求和向客戶端返回響應。
控制器的目的是接收應用的特定請求。路由機制控制哪個控制器接收哪些請求。通常,每個控制器有多個路由,不同的路由可以執行不同的操作。
爲了創建一個基本的控制器,我們使用類和裝飾器
。
裝飾器將類與所需的元數據相關聯,並使 Nest 能夠創建路由映射(將請求綁定到相應的控制器)。
創建控制器
我們先使用 nestCli
工具創建
nest g controller cats
可以看到他是,創建了兩個文件,並且更新了一個文件
我們看下他更新的這個文件,更新了什麼
可以看到增加了這些東西
至於 cats.controller.spec.ts
是自動生成的單元測試樣例,可要可不要
重要的是 cats.controller.ts
這個文件,我們看下這個文件
import { Controller } from '@nestjs/common';
@Controller('cats')
export class CatsController {}
可以看到就幾行代碼,一目瞭然,那後面我們創建控制器,可以採用更方便的方式
直接創建一個文件,並修改下 app.module.ts
文件即可,該文件是應用模塊根模塊
路由
在下面的例子中
我們使用 @Controller()
裝飾器定義一個基本的控制器。可選 路由路徑前綴設置爲 cats
。
在 @Controller()
裝飾器中使用路徑前綴可以使我們輕鬆地對一組相關的路由進行分組
並最大程度地減少重複代碼。
例如
我們可以選擇將一組用於管理與 /customers
下的客戶實體進行互動的路由進行分組。
這樣
我們可以在 @Controller()
裝飾器中指定路徑前綴 customers
這樣就不必爲文件中的每個路由重複路徑的那部分。
import { Controller, Get } from '@nestjs/common';
// 裝飾器
// 聲明控制器,添加了路由組(路由前綴) cats
@Controller('cats')
export class CatsController {
// 綁定到控制器方法, 此時路由爲:/cats//customer
@Get('/customer')
findAll(): string {
return 'This action returns all cats';
}
}
此函數將返回 200
狀態代碼和相關的響應,在本例中只返回了一個字符串。爲什麼會這樣? 爲了解釋原因,首先我們將介紹 Nest 使用兩種不同的操作響應選項的概念:
標準(推薦) | 使用這個內置方法,當請求處理程序返回一個 JavaScript 對象或數組時,它將自動序列化爲 JSON 。但是,當它返回一個 JavaScript 基本類型(例如string、number、boolean )時, Nest 將只發送值,而不嘗試序列化它。這使響應處理變得簡單:只需要返回值,其餘的由 Nest 負責。 |
類庫特有的 | 我們可以在函數簽名處通過 @Res() 注入類庫特定的響應對象(例如, Express )。使用此方法,你就能使用由該響應對象暴露的原生響應處理函數。例如,使用 Express ,您可以使用 response.status(200).send() 構建響應 |
注意!Nest 檢測處理程序何時使用
@Res()
或@Next()
,表明你選擇了特定於庫的選項。如果在一個處理函數上同時使用了這兩個方法,那麼此處的標準方式就是自動禁用此路由, 你將不會得到你想要的結果。如果需要在某個處理函數上同時使用這兩種方法(例如,通過注入響應對象,單獨設置 cookie / header,但把其餘部分留給框架),你必須在裝飾器@Res({ passthrough: true })
中將passthrough
選項設爲true
Request
NestJs 提供了方法參數裝飾器,用來幫助我們快速獲取參數 如下
裝飾器 | 參數 |
---|---|
@Request(),@Req() |
req |
@Response(),@Res()* |
res |
@Next() |
next |
@Session() |
req.session |
@Param(key?: string) |
req.params /req.params[key] |
@Body(key?: string) |
req.body /req.body[key] |
@Query(key?: string) |
req.query /req.query[key] |
@Headers(name?: string) |
req.headers /req.headers[name] |
@Ip() |
req.ip |
@HostParam() |
req.hosts |
獲取get請求傳參
可以使用 Request
裝飾器 或者 Query
裝飾器
通過Request裝飾器
例:
import { Controller, Get, Request } from '@nestjs/common';
// 裝飾器
// 聲明控制器,添加了路由組(路由前綴) cats
@Controller('cats')
export class CatsController {
// 綁定到控制器方法, 此時路由爲:/cats//customer
@Get('/customer')
findAll(@Request() req:any): string {
console.log("req ===========>", req.query);
return 'This action returns all cats';
}
}
通過Query裝飾器
也可以使用Query 直接獲取 不需要在通過req.query 了
例:
import { Controller, Get, Query } from '@nestjs/common';
// 裝飾器
// 聲明控制器,添加了路由組(路由前綴) cats
@Controller('cats')
export class CatsController {
// 綁定到控制器方法, 此時路由爲:/cats//customer
@Get('/customer')
findAll(@Query() query): string {
console.log("query ===========>", query);
return 'This action returns all cats';
}
}
輸出結果跟上面一致
post 獲取參數
可以使用Request
裝飾器 或者 Body
裝飾器
raw json 格式
通過Request裝飾器
import { Controller, Request, Post } from '@nestjs/common';
// 裝飾器
// 聲明控制器,添加了路由組(路由前綴) cats
@Controller('cats')
export class CatsController {
// 綁定到控制器方法, 此時路由爲:/cats//customer
@Post('/customer')
findAll(@Request() request): string {
console.log("request.body ===========>", request.body);
return 'This action returns all cats';
}
}
通過Body 裝飾器
import { Controller, Request, Post, Body } from '@nestjs/common';
// 裝飾器
// 聲明控制器,添加了路由組(路由前綴) cats
@Controller('cats')
export class CatsController {
// 綁定到控制器方法, 此時路由爲:/cats//customer
@Post('/customer')
findAll(@Body() body): string {
console.log("body ===========>", body);
return 'This action returns all cats';
}
}
直接讀取key 也可以
import { Controller, Request, Post, Body } from '@nestjs/common';
// 裝飾器
// 聲明控制器,添加了路由組(路由前綴) cats
@Controller('cats')
export class CatsController {
// 綁定到控制器方法, 此時路由爲:/cats//customer
@Post('/customer')
findAll(@Body('name') name): string {
console.log("name ===========>", name);
return 'This action returns all cats';
}
}
獲取 multipart/form-data
格式 數據
如果表單數據是 multipart/form-data
格式,
那麼可以使用 @UploadedFile()
裝飾器來獲取上傳的文件。
同時,也可以使用 @Body()
裝飾器來獲取除文件外的表單數據。
其中,
@UseInterceptors(FileInterceptor('file'))
裝飾器用於將上傳的文件注入到 file
參數中,
@Body()
裝飾器用於將表單數據注入到 formData
參數中。
需要注意的是,
@UseInterceptors
裝飾器需要使用 @nestjs/platform-express
包中提供的 FileInterceptor
中間件,該中間件會將上傳的文件保存到臨時目錄中,並將文件信息注入到 file
參數中。
案例
import { Controller, Request, Post, Body, UseInterceptors, UploadedFile } from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
// 裝飾器
// 聲明控制器,添加了路由組(路由前綴) cats
@Controller('cats')
export class CatsController {
// 綁定到控制器方法, 此時路由爲:/cats//customer
@Post('/customer')
@UseInterceptors(FileInterceptor('file'))
findAll(@UploadedFile() file: Express.Multer.File, @Body() formData): string {
console.log("file --------->", file);
console.log("formData --------->", formData);
return 'This action returns all cats';
}
}
命名空間“global.Express”沒有已導出的成員“Multer”。
如果出現
這個問題
這個問題通常是由於缺少依賴包 @types/multer
導致的,你可以通過以下命令安裝此依賴包:
npm install --save-dev @types/multer
如果問題仍然存在,可以嘗試清除緩存並重新安裝依賴包:
npm cache clean --force
rm -rf node_modules
npm install
如果還是不行,可以嘗試升級 @types/express
的版本,因爲 @types/multer
依賴於 @types/express
。你可以通過以下命令升級 @types/express
:
npm install --save-dev @types/express@latest
獲取動態路由參數
可以使用Request裝飾器 或者 Param 裝飾器 跟express 完全一樣
通過Request裝飾器
例:
import { Controller, Request, Post, Body, UseInterceptors, UploadedFile, Get } from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
// 裝飾器
// 聲明控制器,添加了路由組(路由前綴) cats
@Controller('cats')
export class CatsController {
// 綁定到控制器方法, 此時路由爲:/cats/customer
@Get('/customer/:id')
findAll(@Request() req): string {
console.log("file --------->", req);
return 'This action returns all cats';
}
}
請求:
http://localhost:3000/cats/customer/1314
結果
通過 params裝飾器
import { Controller, Request, Post, Body, UseInterceptors, UploadedFile, Get, Param } from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
// 裝飾器
// 聲明控制器,添加了路由組(路由前綴) cats
@Controller('cats')
export class CatsController {
// 綁定到控制器方法, 此時路由爲:/cats/customer
@Get('/customer/:id')
findAll(@Param() param): string {
console.log("param --------->", param);
return 'This action returns all cats';
}
}
請求:
http://localhost:3000/cats/customer/1314
結果
獲取header 信息
@Headers() headers
例:
import { Controller, Headers, Post, Body, UseInterceptors, UploadedFile, Get, Param } from '@nestjs/common';
// 裝飾器
// 聲明控制器,添加了路由組(路由前綴) cats
@Controller('cats')
export class CatsController {
// 綁定到控制器方法, 此時路由爲:/cats/customer
@Get('/customer/:id')
findAll(@Headers() headers): string {
console.log("headers --------->", headers);
return 'This action returns all cats';
}
}
狀態碼
使用 HttpCode
裝飾器 控制接口返回的狀態碼
import { Controller, Headers, Post, Body, UseInterceptors, UploadedFile, Get, Param, HttpCode } from '@nestjs/common';
// 裝飾器
// 聲明控制器,添加了路由組(路由前綴) cats
@Controller('cats')
export class CatsController {
// 綁定到控制器方法, 此時路由爲:/cats/customer
@Get('/customer/')
@HttpCode(500)
findAll(@Headers() headers): string {
return 'This action returns all cats';
}
}
結果