Appearance
nestjs 常用代码片段
开发常用模块安装
bcrypt 依赖 python 环境,可以使用 bcryptjs 代替
bash
pnpm i @nestjs/passport passport passport-local @nestjs/jwt passport-jwt bcrypt @nestjs/swagger prisma-binding @prisma/client mockjs @nestjs/config class-validator class-transformer lodash dayjs
bash
pnpm i -D @swc/cli @swc/core @types/passport-local @types/passport-jwt @types/bcrypt prisma @types/lodash @types/dayjs
跨域问题解决
ts
app.enableCors()
添加 api 版本
效果: v1/xxx
ts
app.enableVersioning({ defaultVersion: '1', type: VersioningType.URI })
全局 api 前缀
效果: api/xxx
ts
app.setGlobalPrefix('api')
与 api 版本一起使用效果:
api/v1/xxx
统一返回格式
目标返回结果
json
{
data, // 数据
status: 0, // 接口状态值
extra: {}, // 拓展信息
message: 'success', // 异常信息
success:true // 接口业务返回状态
}
transform.interceptor.ts
ts
import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common'
import { map } from 'rxjs/operators'
import type { Observable } from 'rxjs'
interface Response<T> {
data: T
}
@Injectable()
export class TransformInterceptor<T> implements NestInterceptor<T, Response<T>> {
intercept(context: ExecutionContext, next: CallHandler): Observable<Response<T>> {
return next.handle().pipe(
map(data => ({
data,
status: 0,
extra: {},
message: 'success',
success: true,
})),
)
}
}
main.ts
ts
app.useGlobalInterceptors(new TransformInterceptor())
全局异常拦截
被动异常处理
base.exception.filter.ts
ts
import { ArgumentsHost, Catch, ExceptionFilter, HttpStatus, ServiceUnavailableException } from '@nestjs/common'
@Catch()
export class AllExceptionFilter implements ExceptionFilter {
catch(exception: Error, host: ArgumentsHost) {
const ctx = host.switchToHttp()
const response = ctx.getResponse()
const request = ctx.getRequest()
request.log.error(exception)
response.status(HttpStatus.SERVICE_UNAVAILABLE).send({
statusCode: HttpStatus.SERVICE_UNAVAILABLE,
timestamp: new Date().toISOString(),
path: request.url,
message: new ServiceUnavailableException().getResponse(),
})
}
}
http.exception.filter.ts
ts
import { ArgumentsHost, Catch, ExceptionFilter, HttpException } from '@nestjs/common'
@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
catch(exception: HttpException, host: ArgumentsHost) {
const ctx = host.switchToHttp()
const response = ctx.getResponse()
const request = ctx.getRequest()
const status = exception.getStatus()
response.status(status).send({
statusCode: status,
timestamp: new Date().toISOString(),
path: request.url,
message: exception.getResponse(),
})
}
}
main.ts
ts
app.useGlobalInterceptors(new TransformInterceptor())
app.useGlobalFilters(new AllExceptionFilter(), new HttpExceptionFilter())
主动抛出异常处理
有时我们可以预见代码出现错误,会主动抛出异常,下面代码是对主动抛出指定异常时的处理
business.exception.ts
ts
import { HttpException, HttpStatus } from '@nestjs/common'
import { BUSINESS_ERROR_CODE } from './business.error'
interface BusinessError {
code: number
message: string
}
export class BusinessException extends HttpException {
constructor(err: BusinessError | string) {
if (typeof err === 'string') {
err = {
code: BUSINESS_ERROR_CODE.COMMON,
message: err,
}
}
super(err, HttpStatus.OK)
}
static throwForbidden() {
throw new BusinessException({
code: BUSINESS_ERROR_CODE.ACCESS_FORBIDDEN,
message: '抱歉,您无此权限',
})
}
}
自定义业务错误代码
ts
export const BUSINESS_ERROR_CODE = {
// 公共错误码
COMMON: 10001,
// 特殊错误码
TOKEN_INVALID: 10002,
// 禁止访问
ACCESS_FORBIDDEN: 10003,
// 权限已禁用
PERMISSION_DISABLED: 10003,
// 用户已冻结
USER_DISABLED: 10004,
}
改造 http.exception.filter.ts
ts
import { ArgumentsHost, Catch, ExceptionFilter, HttpException } from '@nestjs/common'
@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
catch(exception: HttpException, host: ArgumentsHost) {
const ctx = host.switchToHttp()
const response = ctx.getResponse()
const request = ctx.getRequest()
const status = exception.getStatus()
if (exception instanceof BusinessException) {
const error = exception.getResponse()
response.status(HttpStatus.OK).send({
data: null,
status: error.code,
extra: {},
message: error.message,
success: false,
})
return
}
response.status(status).send({
statusCode: status,
timestamp: new Date().toISOString(),
path: request.url,
message: exception.getResponse(),
})
}
}
在应用程序中抛出异常示例
ts
@Get('error')
errorFunc(){
const a = {}
try{
console.log(a.b)
}catch(){
throw new BusinessException('参数错误')
}
}