控制器主要是用來處理使用者端傳入的請求並向用戶端返回響應。
它一般是用來做路由導航的,內部路由機制控制哪個控制器接收哪些請求。
為了建立基本控制器,我們需要使用@Controller
裝飾器,裝飾器將類與所需後設資料關聯起來,並使Nest
能夠建立路由對映。
我們使用nest-cli
快速建立一個REST API風格的完整CURD程式碼。
nest g resource nanjiu
在生成的nanjiu資料夾下,我們可以看到有nanjiu.controller.ts
檔案,程式碼如下:
// nanjiu.controller.ts
import { Controller, Get, Post, Body, Patch, Param, Delete, Query } from '@nestjs/common';
import { NanjiuService } from './nanjiu.service';
import { CreateNanjiuDto } from './dto/create-nanjiu.dto';
import { UpdateNanjiuDto } from './dto/update-nanjiu.dto';
@Controller('nanjiu')
export class NanjiuController {
constructor(private readonly nanjiuService: NanjiuService) {}
@Post()
create(@Body() createNanjiuDto: CreateNanjiuDto) {
return this.nanjiuService.create(createNanjiuDto);
}
@Get()
findAll(@Param() params, @Query() query) {
console.log('find', query)
return this.nanjiuService.findAll();
}
@Get(':id')
findOne(@Param('id') id: string) {
return this.nanjiuService.findOne(+id);
}
@Patch(':id')
update(@Param('id') id: string, @Body() updateNanjiuDto: UpdateNanjiuDto) {
return this.nanjiuService.update(+id, updateNanjiuDto);
}
@Delete(':id')
remove(@Param('id') id: string) {
return this.nanjiuService.remove(+id);
}
}
@controller
裝飾器中傳入了nanjiu
引數,表示指定路由字首nanjiu
,在@controller
裝飾器中使用路由字首,可以讓我們很輕鬆地將一組相關路由放在一起集中管理。
比如當我們通過get
方式請求/nanjiu
這個路由時,它應該會走到@get
裝飾器修飾的findAll
方法內
可以使用ApiFox
工具進行介面測試:
從上圖中可以看到我此時的請求路徑是http://localhost:3000/apinanjiu
,是不是很好奇為了什麼多了一層/api
,這是因為我加了一層全域性路由字首
// main.ts
app.setGlobalPrefix('api'); // 全域性路由字首
這裡我們還可以看到狀態碼為200,並且能夠看到findAll
的返回值,就說明此時的請求是正常的,但右邊還有個error提示返回資料結構與介面定義不一致。
這是因為這裡我們只是簡單地返回了一個字串,並不符合JSON格式
在Nest
中,有兩種選項來處理響應值:
標準模式:使用此內建方法,當請求處理程式返回 JavaScript 物件或陣列時,它將自動序列化為 JSON。然而,當它返回 JavaScript 基本型別(例如,string
、number
、boolean
)時,Nest 將僅傳送該值,而不嘗試對其進行序列化。這使得響應處理變得簡單:只需返回值,Nest 就會處理其餘的事情。
此外,預設情況下,響應的狀態程式碼始終為 200,除了使用 201 的 POST 請求。我們可以通過@HttpCode(...)
在處理程式級別新增裝飾器來輕鬆更改此行為
特定庫模式:我們可以使用特定於庫的(例如,Express)響應物件@Res()
,可以使用方法處理程式簽名中的裝飾器注入該物件(例如, findAll(@Res() response)
)。通過這種方法,您可以使用該物件公開的本機響應處理方法。例如,使用 Express,可以使用response.status(200).send()
.
Nest
還支援基於模式的路由,比如,使用萬用字元
@Get('ab*cd')
findAll() {
return 'This route uses a wildcard';
}
路由'ab*cd'
路徑將匹配abcd
、ab_cd
、abecd
等。字元?
、+
、*
和()
可以在路由路徑中使用,並且是其正規表示式對應項的子集。連字元 ( -
) 和點 ( .
) 按字面意思解釋為基於字串的路徑。
作為後端專案,存取使用者端請求的詳細資訊也非常重要,從上面生成的程式碼中我們可以看到@Body
、@Param
、@Query
等裝飾器,沒錯,在大多數時候我們並不需要手動獲取請求物件(查詢字串、引數、請求頭、正文等),直接通過這些開箱即用的裝飾器就能快速獲取。
比如我們在findAll
內加上紀錄檔
// nanjiu.controller.ts
@Get()
findAll(@Param() params, @Query() query) {
console.log('find', params, query) // 紀錄檔
return this.nanjiuService.findAll();
}
然後在請求時帶上一些引數:
此時我們再來看看後端列印的紀錄檔:
這裡就能看到前端請求傳過來的Query
引數為city: shanghai
這些開箱即用的裝飾器有以下這些:
@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
請求方法裝飾器外還有一些其它的,事實上,Nest
為所有標準 HTTP 方法提供了裝飾器:@Get()
、@Post()
、@Put()
、@Delete()
、@Patch()
、@Options()
和@Head()
。
一般大家常用的都是get
請求與post
請求吧,好像很少看到其它型別的請求
這裡可以使用@Request
裝飾器與@Query
裝飾器,與express
完全一致
上面已經演示了通過@Query
獲取,那就在通過@Request
再演示一遍
// nanjiu.controller.ts
@Get()
findAll(@Request() req, @Query() query) {
console.log('find', req.query, query)
return this.nanjiuService.findAll();
}
通過req.query
與Query
獲取的是一致的,所以使用@Query
裝飾器獲取get
型別的請求引數會更方便一些,如果你還想獲取更多關於請求的引數可以使用@Request
裝飾器。
與express
一樣,可以使用@Request
裝飾器與Body
裝飾器
// nanjiu.controller.ts
@Post()
create(@Body() createNanjiuDto: CreateNanjiuDto) {
console.log('body', createNanjiuDto)
return this.nanjiuService.create(createNanjiuDto);
}
檢視紀錄檔
當需要接受動態資料作為請求的一部分(例如,GET /nanjiu/1
獲取帶有 id 為 1
的nanjiu
)時,具有靜態路徑的路由將不起作用。為了定義帶引數的路由,我們可以在路由的路徑中新增路由引數**標記,以捕獲請求 URL 中該位置的動態值。**下面裝飾器範例中的路由引數標記@Get()
演示了這種用法。以這種方式宣告的路由引數可以使用裝飾器來存取@Param()
// nanjiu.controller.ts
@Get(':id')
findOne(@Param() params) {
console.log('params', params)
return this.nanjiuService.findOne(+params.id);
}
檢視紀錄檔
從上面幾個例子我們可以看到,預設情況下響應狀態碼都是200
,POST
請求除外,POST
預設為201
,Nest
同樣提供了HttpCode()
裝飾器來自定義響應狀態碼
// nanjiu.controller.ts
@Get()
@HttpCode(202)
findAll(@Request() req, @Query() query) {
console.log('find', req, query)
return this.nanjiuService.findAll();
}
想要自定義響應頭,可以使用@Header
裝飾器
@Post()
@Header('Cache-Control', 'none')
create(@Body() createNanjiuDto: CreateNanjiuDto) {
console.log('body', createNanjiuDto)
return this.nanjiuService.create(createNanjiuDto);
}
-------------------------------------------
如果這篇文章有幫助到你,❤️關注+點贊❤️鼓勵一下作者,文章公眾號首發,關注 前端南玖 第一時間獲取最新的文章~
掃描下方二維條碼關注公眾號,回覆進群,拉你進前端學習交流群