最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Nest.js參數(shù)校驗(yàn)和自定義返回?cái)?shù)據(jù)格式詳解

 更新時(shí)間:2021年03月28日 11:55:14   作者:Jaxson Wang  
這篇文章主要給大家介紹了關(guān)于Nest.js參數(shù)校驗(yàn)和自定義返回?cái)?shù)據(jù)格式的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

0x0 參數(shù)校驗(yàn)

參數(shù)校驗(yàn)大部分業(yè)務(wù)是使用 Nest.js 中的管道 方法實(shí)現(xiàn),具體可以查閱文檔 。不過(guò)編寫(xiě)過(guò)程中遇到一些問(wèn)題,雖然文檔講得比較晦澀。

在做個(gè)查詢(xún)接口,里面包含一些參數(shù),做成 dto 結(jié)構(gòu)數(shù)據(jù):

import { ApiProperty } from '@nestjs/swagger'

export class QueryUserDto {
 @ApiProperty({
 required: false,
 description: '頁(yè)碼'
 })
 readonly currentPage: number

 @ApiProperty({
 required: false,
 description: '條數(shù)'
 })
 readonly pageSize: number

 @ApiProperty({
 required: false,
 description: '用戶賬號(hào)'
 })
 readonly username?: string

 @ApiProperty({
 required: false,
 description: '用戶狀態(tài)'
 })
 readonly activeStatus: number

 @ApiProperty({
 required: false,
 description: '排序的方式: ASC, DESC'
 })
 readonly order: 'DESC' | 'ASC'
}
 TYPESCRIPT

在 @Query 請(qǐng)求傳入對(duì)應(yīng)的參數(shù),發(fā)現(xiàn)得到的數(shù)據(jù)類(lèi)型都是 String ,然后查閱相關(guān)文檔才明白還需要 class-transformer 的 Type 進(jìn)行轉(zhuǎn)換:

import { ApiProperty } from '@nestjs/swagger'
import { Type } from 'class-transformer'

export class QueryUserDto {
 @ApiProperty({
 required: false,
 description: '頁(yè)碼'
 })
 @Type(() => Number)
 readonly currentPage: number = 1

 @ApiProperty({
 required: false,
 description: '條數(shù)'
 })
 @Type(() => Number)
 readonly pageSize: number = 10

 @ApiProperty({
 required: false,
 description: '用戶賬號(hào)'
 })
 readonly username?: string

 @ApiProperty({
 required: false,
 description: '用戶狀態(tài)'
 })
 @Type(() => Number)
 readonly activeStatus: number = 3

 @ApiProperty({
 required: false,
 description: '排序的方式: ASC, DESC'
 })
 readonly order: 'DESC' | 'ASC' = 'DESC'
}

然后在 ValidationPipe 管道方法里開(kāi)啟 transform 選項(xiàng):

app.useGlobalPipes(
 new ValidationPipe({
 transform: true
 })
)

或者在 app.modules.ts 注入:

import { ValidationPipe } from '@nestjs/common'
import { APP_PIPE } from '@nestjs/core'

@Module({
 imports: [
 // ...
 ],
 controllers: [AppController],
 providers: [
 {
  provide: APP_PIPE,
  useValue: new ValidationPipe({
  transform: true
  })
 }
 ]
})

倆者使用方法區(qū)別于程序的是否混合應(yīng)用類(lèi)型。

我這邊為了省事直接寫(xiě)在全局方法里,最終到 service 拿到的數(shù)據(jù)就是經(jīng)過(guò)管道業(yè)務(wù)處理過(guò)的數(shù)據(jù),不需要在 service 層進(jìn)行大量的數(shù)據(jù)類(lèi)型判斷。

0x1 自定義返回?cái)?shù)據(jù)格式

在 controller 返回的數(shù)據(jù)都是從數(shù)據(jù)庫(kù)表結(jié)構(gòu)而來(lái):

{
 "id": "d8d5a56c-ee9f-4e41-be48-5414a7a5712c",
 "username": "Akeem.Cremin",
 "password": "$2b$10$kRcsmN6ewFC2GOs0TEg6TuvDbNzf1VGCbQf2fI1UeyPAiZCq9rMKm",
 "email": "Garrett87@hotmail.com",
 "nickname": "Wallace Nicolas",
 "role": "user",
 "isActive": true,
 "createdTime": "2021-03-24T15:24:26.806Z",
 "updatedTime": "2021-03-24T15:24:26.806Z"
}

如果需要定義最終返回接口的數(shù)據(jù)格式例如:

{
 "statusCode": 200,
 "message": "獲取成功",
 "data": {
  "id": "d8d5a56c-ee9f-4e41-be48-5414a7a5712c",
  "username": "Akeem.Cremin",
  "password": "$2b$10$kRcsmN6ewFC2GOs0TEg6TuvDbNzf1VGCbQf2fI1UeyPAiZCq9rMKm",
  "email": "Garrett87@hotmail.com",
  "nickname": "Wallace Nicolas",
  "role": "user",
  "isActive": true,
  "createdTime": "2021-03-24T15:24:26.806Z",
  "updatedTime": "2021-03-24T15:24:26.806Z"
 }
}

這里就需要做個(gè)自定義成功請(qǐng)求攔截器:

nest g in shared/interceptor/transform
import { CallHandler, ExecutionContext, Injectable, Logger, NestInterceptor } from '@nestjs/common'
import { Observable } from 'rxjs'
import { map } from 'rxjs/operators'
import { Request } from 'express'

interface Response<T> {
 data: T
}

@Injectable()
export class TransformInterceptor<T> implements NestInterceptor<T, Response<T>> {
 intercept(context: ExecutionContext, next: CallHandler<T>): Observable<any> {
 const request = context.switchToHttp().getRequest<Request>()
 Logger.log(request.url, '正常接口請(qǐng)求')

 return next.handle().pipe(
  map(data => {
  return {
   data: data,
   statusCode: 200,
   message: '請(qǐng)求成功'
  }
  })
 )
 }
}

然后在 app.module.ts 引入即可使用:

import { ValidationPipe } from '@nestjs/common'
import { APP_INTERCEPTOR } from '@nestjs/core'

import { TransformInterceptor } from '@/shared/interceptor/transform.interceptor'

@Module({
 imports: [
 // ...
 ],
 controllers: [AppController],
 providers: [
 {
  provide: APP_INTERCEPTOR,
  useClass: TransformInterceptor
 }
 ]
})

不過(guò) APP_INTERCEPTOR 排序要注意,TransformInterceptor 最好放在第一個(gè),否則會(huì)失效。

錯(cuò)誤過(guò)濾器:

nest g f shared/filters/httpException
import { ArgumentsHost, Catch, ExceptionFilter, HttpException, Logger } from '@nestjs/common'
import { Response, Request } from 'express'

@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
 catch(exception: HttpException, host: ArgumentsHost) {
 const context = host.switchToHttp()
 const response = context.getResponse<Response>()
 const request = context.getRequest<Request>()
 const status = exception.getStatus()
 const message = exception.message

 Logger.log(`${request.url} - ${message}`, '非正常接口請(qǐng)求')

 response.status(status).json({
  statusCode: status,
  message: message,
  path: request.url,
  timestamp: new Date().toISOString()
 })
 }
}

然后在 app.module.ts 引入即可使用:

import { ValidationPipe } from '@nestjs/common'
import { APP_FILTER } from '@nestjs/core'

import { HttpExceptionFilter } from '@/shared/filters/http-exception.filter'

@Module({
 imports: [
 // ...
 ],
 controllers: [AppController],
 providers: [
 {
  provide: APP_FILTER,
  useClass: HttpExceptionFilter
 }
 ]
})

0x2 隱藏實(shí)體類(lèi)中的某個(gè)字段

本來(lái)想使用 @Exclude 屬性來(lái)隱藏?cái)?shù)據(jù)庫(kù)中一些敏感的字段,但發(fā)現(xiàn)無(wú)法滿足特殊的需求,如果是返回單條實(shí)例可以實(shí)現(xiàn)隱藏,但是我有個(gè) findAll 就無(wú)法實(shí)現(xiàn)了,上面在 Serialization | NestJS - A progressive Node.js framework 文檔里說(shuō)的非常詳細(xì),不過(guò)這里還有個(gè)辦法。首先在實(shí)力類(lèi)敏感數(shù)據(jù)字段上添加屬性:

import { BaseEntity, Entity, Column, PrimaryGeneratedColumn } from 'typeorm'

@Entity('user')
export class UserEntity extends BaseEntity {
 @PrimaryGeneratedColumn('uuid', {
  comment: '用戶編號(hào)'
 })
 id: string

 @Column({
  type: 'varchar',
  length: 50,
  unique: true,
  comment: '登錄用戶'
 })
 username: string

 @Column({
  type: 'varchar',
  length: 200,
  select: false,
  comment: '密碼'
 })
 password: string

select: false 可以在返回查詢(xún)結(jié)果隱藏這個(gè)字段,但所有涉及到這個(gè)字段查詢(xún)必須添加這個(gè)字段,比如我在 user.service.ts 登錄查詢(xún)中:

const user = await getRepository(UserEntity)
   .createQueryBuilder('user')
   .where('user.username = :username', { username })
   .addSelect('user.password')
   .getOne()

.addSelect('user.password') 添加這個(gè)屬性查詢(xún)將會(huì)包括 password 這個(gè)字段,否則普通查詢(xún)的方法不會(huì)包括這個(gè)字段。

總結(jié)

到此這篇關(guān)于Nest.js參數(shù)校驗(yàn)和自定義返回?cái)?shù)據(jù)格式的文章就介紹到這了,更多相關(guān)Nest.js參數(shù)校驗(yàn)和數(shù)據(jù)格式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Node.js 回調(diào)函數(shù)實(shí)例詳解

    Node.js 回調(diào)函數(shù)實(shí)例詳解

    這篇文章主要介紹了Node.js 回調(diào)函數(shù)實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下
    2017-07-07
  • Node.js巧妙實(shí)現(xiàn)Web應(yīng)用代碼熱更新

    Node.js巧妙實(shí)現(xiàn)Web應(yīng)用代碼熱更新

    本文給大家講解的是Node.js的代碼熱更新的問(wèn)題,其主要實(shí)現(xiàn)原理 是怎么對(duì) module 對(duì)象做處理,也就是手工監(jiān)聽(tīng)文件修改, 然后清楚模塊緩存, 重新掛載模塊,思路清晰考慮細(xì)致, 雖然有點(diǎn)冗余代碼,但還是推薦給大家
    2015-10-10
  • 詳解nodejs http請(qǐng)求相關(guān)總結(jié)

    詳解nodejs http請(qǐng)求相關(guān)總結(jié)

    這篇文章主要介紹了nodejs http請(qǐng)求相關(guān)總結(jié),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-03-03
  • pnpm實(shí)現(xiàn)依賴(lài)包共享和依賴(lài)包項(xiàng)目隔離的方法詳解

    pnpm實(shí)現(xiàn)依賴(lài)包共享和依賴(lài)包項(xiàng)目隔離的方法詳解

    pnpm是Node.js的包管理器,它是 npm 的直接替代品,相對(duì)于npm和yarn它的優(yōu)點(diǎn)就在于速度快和高效節(jié)省磁盤(pán)空間,本文主要講解pnpm相比于npm/yarn如何利用軟硬鏈接來(lái)節(jié)省磁盤(pán)空間,以及如何實(shí)現(xiàn)依賴(lài)包共享和依賴(lài)包項(xiàng)目隔離的,需要的朋友可以參考下
    2024-05-05
  • nodejs使用node-xlsx生成excel的方法示例

    nodejs使用node-xlsx生成excel的方法示例

    這篇文章主要介紹了nodejs使用node-xlsx生成excel,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • node連接MySQL數(shù)據(jù)庫(kù)的3種方式總結(jié)

    node連接MySQL數(shù)據(jù)庫(kù)的3種方式總結(jié)

    現(xiàn)在前端基本上都會(huì)用一些NodeJs,想必也想自己寫(xiě)一些API或者個(gè)人博客的后臺(tái)系統(tǒng),這些就離不開(kāi)連接數(shù)據(jù)庫(kù)的問(wèn)題,下面這篇文章主要給大家介紹了關(guān)于node連接MySQL數(shù)據(jù)庫(kù)的3種方式,需要的朋友可以參考下
    2022-08-08
  • 詳解兩個(gè)Node.js進(jìn)程是如何通信

    詳解兩個(gè)Node.js進(jìn)程是如何通信

    進(jìn)程間通信是是Node.js的一個(gè)十分重要的部分,這篇文章主要給大家介紹了關(guān)于兩個(gè)Node.js進(jìn)程是如何通信的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2021-10-10
  • NodeJS Web應(yīng)用監(jiān)聽(tīng)sock文件實(shí)例

    NodeJS Web應(yīng)用監(jiān)聽(tīng)sock文件實(shí)例

    這篇文章主要介紹了NodeJS Web應(yīng)用監(jiān)聽(tīng)sock文件實(shí)例,本文講解 NodeJS 的 TCP 和 HTTP 監(jiān)聽(tīng) Domain Socket 文件例子,需要的朋友可以參考下
    2015-02-02
  • 關(guān)于npm install報(bào)錯(cuò)ERR code ETIMEDOUT的問(wèn)題及解決

    關(guān)于npm install報(bào)錯(cuò)ERR code ETIMEDOUT的問(wèn)題及解決

    這篇文章主要介紹了關(guān)于npm install報(bào)錯(cuò)ERR code ETIMEDOUT的問(wèn)題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-06-06
  • 詳解Node.js中的事件機(jī)制

    詳解Node.js中的事件機(jī)制

    Node.js能夠在眾多的后端JavaScript技術(shù)之中脫穎而出,正是因其基于事件的特點(diǎn)而受到歡迎,所以這篇文章小編給大家詳細(xì)介紹了Node.js中的事件機(jī)制,本文介紹的很詳細(xì),對(duì)大家的理解和學(xué)習(xí)很有幫助,下面來(lái)一起看看吧。
    2016-09-09

最新評(píng)論

正镶白旗| 裕民县| 南宁市| 深圳市| 长白| 白水县| 邓州市| 阜新| 土默特左旗| 安陆市| 伊宁县| 扎兰屯市| 绥棱县| 湘西| 左贡县| 日土县| 浦东新区| 宜兴市| 改则县| 虞城县| 增城市| 建昌县| 大同县| 玉门市| 双流县| 广灵县| 松溪县| 松潘县| 浮山县| 潜山县| 合作市| 贺兰县| 大化| 唐山市| 龙里县| 冀州市| 五莲县| 高唐县| 尼勒克县| 鹤峰县| 特克斯县|