- 创建项目
- Nest 控制器
- nest 配置路由请求数据
- Nest 服务
- Nest 模块
- 配置静态资源
- 配置模板引擎
- Cookie 的使用
- Session 的使用
- 跨域,前缀路径、网站安全、请求限速
- 管道、守卫、拦截器、过滤器、中间件
- 一例看懂中间件、守卫、管道、异常过滤器、拦截器
- 数据验证
- 配置抽离
- 环境配置
- 文件上传与下载
- 实现图片随机验证码
- 邮件服务
- nest 基于 possport + jwt 做登陆验证
- 对数据库的密码加密:md5 和 bcryptjs
- 角色权限
- 定时任务
- 接入 Swagger 接口文档
- nest 连接 Mongodb
- typeORM 操作 Mysql 数据库
- nest 统一处理数据库操作的查询结果
- 数据库实体设计与操作
- typeorm 增删改查操作
- typeorm 使用事务的 3 种方式
- typeorm 一对一关系设计与增删改查
- typeorm 一对多和多对一关系设计与增删改查
- typeorm 多对多关系设计与增删改查
- nest 连接 Redis
- 集成 redis 实现单点登录
- Q:nestJS 注入其他依赖时为什么还需要导入其 module
文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
nest 统一处理数据库操作的查询结果
操作数据库时,如何做异常处异常? 比如 id 不存在,用户名已经存在?如何统一处理请求失败和请求成功?
处理方式:
- 在 nest 中,一般是在service中处理异常,如果有异常,直接抛出错误,由过滤器捕获,统一格式返回,如果成功,service 把结果返回,controller 直接 return 结果即可,由拦截器捕获,统一格式返回
- 失败:过滤器统一处理
- 成功:拦截器统一处理
- 当然你也可以在
controller
处理
// user.controller.ts import { Controller, Get, Post, Body, HttpCode, HttpStatus, } from '@nestjs/common'; import { UserService } from './user.service'; @Controller('user') export class UserController { constructor(private readonly userService: UserService) { } @Post() @HttpCode(HttpStatus.OK) //创建成功返回的是 201 状态码,这里重置为 200,需要用到的可以使用 HttpCode 设置 async create(@Body() user) { return await this.userService.create(user); } @Get(':id') async findOne(@Param('id') id: string) { return await this.userService.findOne(id); } }
// user.service.ts import { Injectable, HttpException, HttpStatus } from '@nestjs/common'; import { Repository } from 'typeorm'; import { InjectRepository } from '@nestjs/typeorm'; import { UsersEntity } from './entities/user.entity'; @Injectable() export class UserService { constructor( @InjectRepository(UsersEntity) private readonly usersRepository: Repository<UsersEntity> ) { } async create(user) { const { username } = user; const result = await this.usersRepository.findOne({ username }); if (result) { //如果用户名已经存在,抛出错误 throw new HttpException( { message: '请求失败', error: '用户名已存在' }, HttpStatus.BAD_REQUEST, ); } return await this.usersRepository.save(user); } async findOne(id: string) { const result = await this.usersRepository.findOne(id); if (!result) { //如果用户 id 不存在,抛出错误 throw new HttpException( { message: '请求失败', error: '用户 id 不存在' }, HttpStatus.BAD_REQUEST, ); } return result; } }
可以将 HttpException
再简单封装一下,或者使用继承,这样代码更简洁一些
import { Injectable, HttpException, HttpStatus } from '@nestjs/common'; @Injectable() export class ToolsService { static fail(error, status = HttpStatus.BAD_REQUEST) { throw new HttpException( { message: '请求失败', error: error, }, status, ); } }
简洁代码
// user.service.ts import { Injectable, HttpException, HttpStatus } from '@nestjs/common'; import { Repository } from 'typeorm'; import { InjectRepository } from '@nestjs/typeorm'; import { UsersEntity } from './entities/user.entity'; import { ToolsService } from '../../utils/tools.service'; @Injectable() export class UserService { constructor( @InjectRepository(UsersEntity) private readonly usersRepository: Repository<UsersEntity> ) { } async create(user) { const { username } = user; const result = await this.usersRepository.findOne({ username }); if (result) ToolsService.fail('用户名已存在'); return await this.usersRepository.save(user); } async findOne(id: string) { const result = await this.usersRepository.findOne(id); if (!result) ToolsService.fail('用户 id 不存在'); return result; } }
全局使用 filter 过滤器
// src/common/filters/http-execption.ts import { ArgumentsHost, Catch, ExceptionFilter, HttpException, } from '@nestjs/common'; @Catch() 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(); const exceptionRes: any = exception.getResponse(); const { error, message } = exceptionRes; const msgLog = { status, message, error, path: request.url, timestamp: new Date().toISOString(), }; response.status(status).json(msgLog); } }
全局使用 interceptor 拦截器
// src/common/inteptors/transform.interceptor.ts import { CallHandler, ExecutionContext, Injectable, NestInterceptor, } from '@nestjs/common'; import { map } from 'rxjs/operators'; import { Observable } from 'rxjs'; @Injectable() export class AuthInterceptor implements NestInterceptor { intercept(context: ExecutionContext, next: CallHandler): Observable<any> { return next.handle().pipe( map((data) => { return { status: 200, message: '请求成功', data: data, }; }), ); } }
// main.ts import { HttpExceptionFilter } from './common/filters/http-exception.filter'; import { TransformInterceptor } from './common/interceptors/transform.interceptor'; async function bootstrap() { // 创建实例 const app = await NestFactory.create<NestExpressApplication>(AppModule); // 全局过滤器 app.useGlobalFilters(new HttpExceptionFilter()); // 全局拦截器 app.useGlobalInterceptors(new TransformInterceptor()); // 启动端口 const PORT = process.env.PORT || 9000; await app.listen(PORT, () => Logger.log(`服务已经启动 http://localhost:${PORT}`), ); } bootstrap();
失败
成功
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论