nestJs 控制器

參考:

https://docs.nestjs.cn/9/controllers

控制器負責處理傳入的請求和向客戶端返回響應

img

控制器的目的是接收應用的特定請求。路由機制控制哪個控制器接收哪些請求。通常,每個控制器有多個路由,不同的路由可以執行不同的操作。

爲了創建一個基本的控制器,我們使用類和裝飾器

裝飾器將類與所需的元數據相關聯,並使 Nest 能夠創建路由映射(將請求綁定到相應的控制器)。

創建控制器

我們先使用 nestCli 工具創建

nest g controller cats

image-20230330153112958

可以看到他是,創建了兩個文件,並且更新了一個文件

我們看下他更新的這個文件,更新了什麼

image-20230330153358935

可以看到增加了這些東西

至於 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';
  }
}

image-20230330175027748

image-20230330175111494

通過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';
  }
}

image-20230331093930440

image-20230331094026587

通過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';
  }
}

image-20230331101929610

直接讀取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';
  }
}

image-20230331105434348

image-20230331105518177

命名空間“global.Express”沒有已導出的成員“Multer”。

如果出現

image-20230331104954335

這個問題

這個問題通常是由於缺少依賴包 @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

結果

image-20230331110611953

通過 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

結果

image-20230331110849036

獲取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';
  }
}

image-20230331111556439

狀態碼

使用 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';
  }
}

結果

image-20230331112010829

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章