日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

2. Nest:Controller

發布時間:2025/3/21 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2. Nest:Controller 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

控制器

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

轉存失敗重新上傳取消

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

為了創建一個基本的控制器,我們必須使用裝飾器。裝飾器將類與所需的元數據關聯,并使?Nest?能夠創建路由映射(將請求綁定到相應的控制器)。

路由

在下面的例子中,我們使用了定義基本控制器所需的?@Controller('cats')?裝飾器。我們將可選前綴設置為?cats。使用前綴可以避免在所有路由共享通用前綴時出現沖突的情況。我們將使用?@Controller()?裝飾器,這是定義基本控制器所必需的。我們將指定一個路徑前綴(可選)?cats。在?@Controller()?裝飾器中使用路徑前綴,它允許我們輕松對一組相關路由進行分組,并減少重復代碼。例如,我們可以選擇管理該路由下的客戶實體的交互的這部分進行分組?/customers?,這樣, 我們可以在?@Controller()?裝飾器中指定路徑前綴, 這樣我們就不必為文件中的每個路由重新定義前綴。

cats.controller.ts

import { Controller, Get } from '@nestjs/common';@Controller('cats') export class CatsController {@Get()findAll(): string {return 'This action returns all cats';} }Copy to clipboardErrorCopied

要使用 CLI 創建控制器,只需執行?$ nest g controller cats?命令。

findAll()方法之前的?@Get()?HTTP?請求方法裝飾器告訴?Nest?為HTTP請求的特定端點創建處理程序。端點對應于?HTTP?請求方法(在本例中為 GET)和路由。什么是路由 ? 處理程序的路由是通過連接為控制器聲明的(可選)前綴和請求裝飾器中指定的任何路由來確定的。由于我們已經為每個?route(cats) 聲明了一個前綴,并且沒有在裝飾器中添加任何路由信息,因此 Nest會將?GET /cats?請求映射到此處理程序。如上所述,該路由包括可選的控制器路由前綴和請求方法裝飾器中聲明的任何路由。例如,customers?與裝飾器組合的路由前綴?@Get('profile')?會為請求生成路由映射?GET /customers/profile。

在上面的示例中,當對此端點發出?GET?請求時,Nest?會將請求路由到我們的用戶定義?findAll()?方法。請注意,我們在此處選擇的函數名稱完全是任意的。我們顯然必須聲明一個綁定路由的函數,但?Nest?不會對所選的函數名稱附加任何意義。

此函數將返回?200?狀態代碼和相關的響應,在這種情況下只返回了一個字符串。為什么會這樣? 我們將首先介紹?Nest?使用兩種不同的操作響應選項的概念:

??
標準(推薦)使用這個內置方法,當請求處理程序返回一個?JavaScript?對象或數組時,它將自動序列化為?JSON。但是,當它返回一個?JavaScript?基本類型(例如string、number、boolean)時,Nest?將只發送值,而不嘗試序列化它。這使響應處理變得簡單:只需要返回值,其余的由?Nest負責。
?此外,響應的狀態碼默認情況下始終為?200,但使用?201?的?POST請求除外。我們可以通過在處理程序級別添加?@HttpCode(...)?裝飾器來輕松更改此行為 (狀態代碼)
類庫特有的我們可以在函數簽名通過?@Res()?注入類庫特定的 響應對象(例如,Express),使用此函數,您具有使用該對象的響應處理函數。例如,使用?Express,您可以使用類似代碼構建響應?response.status(200).send()

注意! 禁止同時使用這兩種方法。?Nest?檢測處理程序是否正在使用?@Res()或?@Next(),如果兩個方法都用了的話, 那么在這里的標準方式就是自動禁用此路由, 你將不會得到你想要的結果。

Request

許多端點需要訪問客戶端的請求細節。實際上,Nest?正使用類庫特有(默認是express)的請求對象。因此,我們可以強制?Nest?使用?@Req()?裝飾器將請求對象注入處理程序。

cats.controller.ts

import { Controller, Get, Req } from '@nestjs/common'; import { Request } from 'express';@Controller('cats') export class CatsController {@Get()findAll(@Req() request: Request): string {return 'This action returns all cats';} }Copy to clipboardErrorCopied

為了在?express?中使用?Typescript?(如?request: Request?上面的參數示例所示),請安裝?@types/express?。

Request?對象表示?HTTP?請求,并具有?Request?查詢字符串,參數,HTTP?標頭 和 正文的屬性(在這里),但在大多數情況下, 不必手動獲取它們。 我們可以使用專用的裝飾器,比如開箱即用的?@Body()?或?@Query()?。 下面是裝飾器和 普通表達對象的比較。

??
@Request()req
@Response()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]

為了與底層?HTTP平臺(如?Express和?Fastify)之間的類型兼容,Nest?提供了?@Res()和?@Response()?裝飾器。@Res()只是?@Response()的別名。兩者都直接公開底層響應對象接口。在使用它們時,您還應該導入底層庫的類型(例如:@types/express)以充分利用它們。注意,在方法處理程序中注入?@Res()或?@Response()?時,將?Nest置于該處理程序的特定于庫的模式中,并負責管理響應。這樣做時,必須通過調用響應對象(例如,res.json(…)或?res.send(…))發出某種響應,否則HTTP服務器將掛起。

想要了解如何創建自定義的裝飾器,閱讀這一章。

資源

我們已經創建了一個端點來獲取數據(GET?路由)。 我們通常還希望提供一個創建新記錄的端點。為此,讓我們創建?POST?處理程序:

cats.controller.ts

import { Controller, Get, Post } from '@nestjs/common';@Controller('cats') export class CatsController {@Post()create(): string {return 'This action adds a new cat';}@Get()findAll(): string {return 'This action returns all cats';} }Copy to clipboardErrorCopied

就這么簡單。Nest以相同的方式提供其余的端點裝飾器-?@Put()?、?@Delete()、?@Patch()、?@Options()、?@Head()和?@All()。這些表示各自的?HTTP請求方法。

路由通配符

路由同樣支持模式匹配。例如,星號被用作通配符,將匹配任何字符組合。

@Get('ab*cd') findAll() {return 'This route uses a wildcard'; }Copy to clipboardErrorCopied

以上路由地址將匹配?abcd?、?ab_cd?、?abecd?等。字符???、?+?、?*?以及?()?是它們的正則表達式對應項的子集。連字符 (-) 和點 (.) 按字符串路徑解析。

狀態碼

如前面所說,默認情況下,響應的狀態碼總是200,除了 POST 請求外,此時它是201,我們可以通過在處理程序層添加@HttpCode(...)?裝飾器來輕松更改此行為。

@Post() @HttpCode(204) create() {return 'This action adds a new cat'; }Copy to clipboardErrorCopied

HttpCode?需要從?@nestjs/common?包導入。

通常,狀態碼不是固定的,而是取決于各種因素。在這種情況下,您可以使用類庫特有的的響應(通過@Res()注入 )對象(或者,在出現錯誤時,拋出異常)。

Headers

要指定自定義響應頭,可以使用?@header()?修飾器或類庫特有的響應對象,(使用 并?res.header()直接調用)。

@Post() @Header('Cache-Control', 'none') create() {return 'This action adds a new cat'; }Copy to clipboardErrorCopied

Header?需要從?@nestjs/common?包導入。

重定向

要將響應重定向到特定的?URL,可以使用?@Redirect()裝飾器或特定于庫的響應對象(并直接調用?res.redirect())。

@Redirect()?帶有必需的?url參數和可選的?statusCode參數。 如果省略,則?statusCode?默認為?302。

@Get() @Redirect('https://nestjs.com', 301)Copy to clipboardErrorCopied

有時您可能想動態確定HTTP狀態代碼或重定向URL。通過從路由處理程序方法返回一個形狀為以下形式的對象:

{"url": string,"statusCode": number }Copy to clipboardErrorCopied

返回的值將覆蓋傳遞給?@Redirect()裝飾器的所有參數。 例如:

@Get('docs') @Redirect('https://docs.nestjs.com', 302) getDocs(@Query('version') version) {if (version && version === '5') {return { url: 'https://docs.nestjs.com/v5/' };} }Copy to clipboardErrorCopied

路由參數

當您需要接受動態數據作為請求的一部分時(例如,使用GET?/cats/1來獲取?id為?1的?cat),帶有靜態路徑的路由將無法工作。為了定義帶參數的路由,我們可以在路由中添加路由參數標記,以捕獲請求?URL?中該位置的動態值。@Get()?下面的裝飾器示例中的路由參數標記演示了此用法。可以使用?@Param()?裝飾器訪問以這種方式聲明的路由參數,該裝飾器應添加到函數簽名中。

@Get(':id') findOne(@Param() params): string {console.log(params.id);return `This action returns a #${params.id} cat`; }Copy to clipboardErrorCopied

@Param()用于修飾方法參數(上面示例中的參數),并使路由參數可用作該修飾的方法參數在方法體內的屬性。 如上面的代碼所示,我們可以通過引用?params.id來訪問?id參數。 您還可以將特定的參數標記傳遞給裝飾器,然后在方法主體中按名稱直接引用路由參數。

Param?需要從?@nestjs/common?包導入。

@Get(':id') findOne(@Param('id') id): string {return `This action returns a #${id} cat`; }Copy to clipboardErrorCopied

范圍

對于來自不同編程語言背景的人來說,了解在?Nest?中幾乎所有內容都可以在傳入的請求之間共享,這讓人意外。比如我們有一個數據庫連接池,具有全局狀態的單例服務等。請記住,Node.js?不遵循請求/響應多線程無狀態模型,每個請求都由主線程處理。因此,使用單例實例對我們的應用程序來說是完全安全的。

但是,存在基于請求的控制器生命周期可能是期望行為的邊緣情況,例如?GraphQL?應用程序中的請求緩存,比如請求跟蹤或多租戶。在這里學習如何控制范圍。

Async / await

我們喜歡現代?JavaScript,而且我們知道數據讀取大多是異步的。 這就是為什么?Nest?支持?async?并且與他們一起工作得非常好。

了解更多關于?Async / await?請點擊這里

每個異步函數都必須返回?Promise。這意味著您可以返回延遲值, 而?Nest?將自行解析它。讓我們看看下面的例子:

cats.controller.ts

@Get() async findAll(): Promise<any[]> {return []; }Copy to clipboardErrorCopied

這是完全有效的。此外,通過返回?RxJS?observable 流。?Nest?路由處理程序更強大。Nest?將自動訂閱下面的源并獲取最后發出的值(在流完成后)。

cats.controller.ts

@Get() findAll(): Observable<any[]> {return of([]); }Copy to clipboardErrorCopied

上面的方法都可以, 你可以選擇你喜歡的方式。

請求負載

之前的?POST?路由處理程序不接受任何客戶端參數。我們在這里添加?@Body()?參數來解決這個問題。

首先(如果您使用?TypeScript),我們需要確定?DTO(數據傳輸對象)模式。DTO是一個對象,它定義了如何通過網絡發送數據。我們可以通過使用?TypeScript接口或簡單的類來完成。令人驚訝的是,我們在這里推薦使用類。為什么?類是JavaScript?ES6標準的一部分,因此它們在編譯后的?JavaScript中保留為實際實體。另一方面,由于?TypeScript接口在轉換過程中被刪除,所以?Nest不能在運行時引用它們。這一點很重要,因為諸如管道之類的特性在運行時能夠訪問變量的元類型時提供更多的可能性。

我們來創建?CreateCatDto?類:

create-cat.dto.ts

export class CreateCatDto {readonly name: string;readonly age: number;readonly breed: string; }Copy to clipboardErrorCopied

它只有三個基本屬性。 之后,我們可以在?CatsController中使用新創建的DTO:

cats.controller.ts

@Post() async create(@Body() createCatDto: CreateCatDto) {return 'This action adds a new cat'; }Copy to clipboardErrorCopied

處理錯誤

這里有一章關于處理錯誤(即處理異常)的單獨章節。

完整示例

下面是一個示例,該示例利用幾個可用的裝飾器來創建基本控制器。 該控制器公開了幾種訪問和操作內部數據的方法。

cats.controller.ts

import { Controller, Get, Query, Post, Body, Put, Param, Delete } from '@nestjs/common'; import { CreateCatDto, UpdateCatDto, ListAllEntities } from './dto';@Controller('cats') export class CatsController {@Post()create(@Body() createCatDto: CreateCatDto) {return 'This action adds a new cat';}@Get()findAll(@Query() query: ListAllEntities) {return `This action returns all cats (limit: ${query.limit} items)`;}@Get(':id')findOne(@Param('id') id: string) {return `This action returns a #${id} cat`;}@Put(':id')update(@Param('id') id: string, @Body() updateCatDto: UpdateCatDto) {return `This action updates a #${id} cat`;}@Delete(':id')remove(@Param('id') id: string) {return `This action removes a #${id} cat`;} }Copy to clipboardErrorCopied

最后一步

控制器已經準備就緒,可以使用,但是?Nest?不知道?CatsController?是否存在,所以它不會創建這個類的一個實例。

控制器總是屬于模塊,這就是為什么我們將?controllers?數組保存在?@module()?裝飾器中。 由于除了根?ApplicationModule,我們沒有其他模塊,所以我們將使用它來介紹?CatsController:

app.module.ts

import { Module } from '@nestjs/common'; import { CatsController } from './cats/cats.controller';@Module({controllers: [CatsController], }) export class AppModule {}Copy to clipboardErrorCopied

我們使用?@Module()裝飾器將元數據附加到模塊類,Nest?現在可以輕松反映必須安裝的控制器。

類庫特有方式

到目前為止,我們已經討論了?Nest?操作響應的標準方式。操作響應的第二種方法是使用類庫特有的響應對象(Response)。為了注入特定的響應對象,我們需要使用?@Res()?裝飾器。為了對比差異,我們重寫?CatsController?:

import { Controller, Get, Post, Res, HttpStatus } from '@nestjs/common'; import { Response } from 'express';@Controller('cats') export class CatsController {@Post()create(@Res() res: Response) {res.status(HttpStatus.CREATED).send();}@Get()findAll(@Res() res: Response) {res.status(HttpStatus.OK).json([]);} }Copy to clipboardErrorCopied

雖然這種方法有效,并且事實上通過提供響應對象的完全控制(標準操作,庫特定的功能等)在某些方面允許更多的靈活性,但應謹慎使用。這種方式非常不清晰,并且有一些缺點。 主要是失去了與依賴于?Nest?標準響應處理的?Nest?功能的兼容性,例如攔截器和?@HttpCode()?裝飾器。此外,您的代碼可能變得依賴于平臺(因為底層庫可能在響應對象上有不同的?API),并且更難測試(您必須模擬響應對象等)。

因此,在可能的情況下,應始終首選?Nest?標準方法。

總結

以上是生活随笔為你收集整理的2. Nest:Controller的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。