Vue3 + Nest 实现权限管理系统 后端篇(一):NestJS入门与基础配置(下)

简介: Vue3 + Nest 实现权限管理系统 后端篇(一):NestJS入门与基础配置(下)


统一的异常处理器



有时候前端会进行一些错误的请求,这时候我们需要返回给他一个异常告知他的请求有问题,我们可以使用 NestJS 内置的异常处理HttpException比如

throw new HttpException('您无权登录', HttpStatus.FORBIDDEN);

客户端就会收到

{
  "statusCode": 403,
  "message": "您无权登录"
}

但是这样不够灵活,所以我们可以新建一个异常过滤器进行自定义的操作

nest g filter common/filter/http-exception

然后修改common/filter/http-exception/http-exception.filter.ts

import {
  ExceptionFilter,
  Catch,
  ArgumentsHost,
  HttpException,
} from '@nestjs/common';
import { Request, Response } from 'express';
@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
  catch(exception: HttpException, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse<Response>();
    const request = ctx.getRequest<Request>();
    const status = exception.getStatus();
    response.status(status).json({
      code: status,
      timestamp: new Date().toISOString(),
      path: request.url,
      describe: exception.message,
    });
  }
}

最后在main.ts中进行注册

import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";
import { HttpExceptionFilter } from "./common/filter/http-exception/http-exception.filter";
async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  //看这里看这里看这里~
  app.useGlobalFilters(new HttpExceptionFilter());
  await app.listen(3000);
}
bootstrap();

user.service.ts的 findAll 测试一下

async findAll() {
    throw new HttpException('禁止访问', HttpStatus.FORBIDDEN);
    return await this.userRepository.find();
  }

前端就会收到错误信息的返回

image.png


返回格式化拦截器



我们还需要一个返回格式的拦截器对请求成功(状态码为 2xx)的数据进行一个格式化,比如返回这样的格式

{
    data:业务参数,
    code:状态码,
    describe:状态描述
    ...
}

同样的先执行

nest g interceptor common/interceptor/transform

创建一个拦截器,按照官网示例给的复制过来

import {
  Injectable,
  NestInterceptor,
  ExecutionContext,
  CallHandler,
} from "@nestjs/common";
import { Observable } from "rxjs";
import { map } from "rxjs/operators";
export 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) => ({ code: 200, data, describe: "请求成功" })));
  }
}

和过滤器一样在main.ts中注册

import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";
import { HttpExceptionFilter } from "./common/filter/http-exception/http-exception.filter";
import { TransformInterceptor } from "./common/interceptor/transform/transform.interceptor";
async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  //看这里看这里看这里~
  app.useGlobalFilters(new HttpExceptionFilter());
  app.useGlobalInterceptors(new TransformInterceptor());
  await app.listen(3000);
}
bootstrap();

我们再将findAll函数改为请求成功的状态

async findAll() {
    return await this.userRepository.find();
  }

进行请求就会发现数据已经被格式化了

image.png

但是这样做之后我们会发现请求成功的 code 只能是 200,一般项目中请求成功还需要很多业务异常状态码返回给前端,所以我们需要新建一个抛出业务异常的类ApiException我们先创建common/enums/api-error-code.enum.ts用于存放我们的业务状态码,这里简单写几个

export enum ApiErrorCode {
  SUCCESS = 200, // 成功
  USER_ID_INVALID = 10001, // 用户id无效
  USER_NOTEXIST = 10002, // 用户id无效
}

         

然后在http-exception中新建api.exception.ts,创建一个ApiException类继承HttpException,接受三个参数错误信息,错误码code,http状态码(默认是200)

import { HttpException, HttpStatus } from '@nestjs/common';
import { ApiErrorCode } from '../../enums/api-error-code.enum';
export class ApiException extends HttpException {
  private errorMessage: string;
  private errorCode: ApiErrorCode;
  constructor(
    errorMessage: string,
    errorCode: ApiErrorCode,
    statusCode: HttpStatus = HttpStatus.OK,
  ) {
    super(errorMessage, statusCode);
    this.errorMessage = errorMessage;
    this.errorCode = errorCode;
  }
  getErrorCode(): ApiErrorCode {
    return this.errorCode;
  }
  getErrorMessage(): string {
    return this.errorMessage;
  }
}

然后修改http-exception.filter.ts,可以判断exception是否在ApiException原型链上来确定是调用的是ApiException还是HttpException

import {
  ExceptionFilter,
  Catch,
  ArgumentsHost,
  HttpException,
} from '@nestjs/common';
import { Request, Response } from 'express';
import { ApiException } from './api.exception';
@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
  catch(exception: HttpException, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse<Response>();
    const request = ctx.getRequest<Request>();
    const status = exception.getStatus();
    if (exception instanceof ApiException) {
      response.status(status).json({
        code: exception.getErrorCode(),
        timestamp: new Date().toISOString(),
        path: request.url,
        describe: exception.getErrorMessage(),
      });
      return;
    }
    response.status(status).json({
      code: status,
      timestamp: new Date().toISOString(),
      path: request.url,
      describe: exception.message,
    });
  }
}

然后在 findAll 函数中抛出一个业务异常

async findAll() {
    throw new ApiException('用户不存在', ApiErrorCode.USER_NOTEXIST);
    return await this.userRepository.find();
  }

然后进行请求

image.png

此时你会发现请求是成功的,但是 code 值是异常的,符合我们的预期

到这里NestJS的基本配置已经做完了,后续便可直接开始我们业务的开发了,欢迎点赞收藏加关注!

相关文章
|
17天前
|
缓存 架构师 数据库
后端开发的艺术:从入门到精通的旅程####
本文旨在探索后端开发的本质与魅力,通过一段段深入浅出的故事,串联起后端技术的精髓。不同于传统的技术总结,这里我们将以一位普通开发者的成长轨迹为线索,展现从初识编程到成为后端架构师的心路历程。每个阶段都伴随着挑战、学习与突破,最终揭示了技术背后的人文关怀与创新精神。 ####
|
22天前
|
存储 缓存 监控
构建高效后端系统的关键要素
【10月更文挑战第12天】 本文将探讨如何通过合理的架构设计、数据库优化、缓存策略和性能调优等措施,构建一个稳定、高效的后端系统。我们将分享一些实用的技巧和最佳实践,帮助开发者提升后端系统的性能和用户体验。
28 1
|
24天前
|
存储 JavaScript 前端开发
前端开发:Vue.js入门与实战
【10月更文挑战第9天】前端开发:Vue.js入门与实战
|
26天前
|
JavaScript API 开发者
十分钟 带你强势入门 vue3
十分钟 带你强势入门 vue3
60 1
|
7天前
|
监控 API 持续交付
后端开发中的微服务架构:从入门到精通
【10月更文挑战第26天】 在当今的软件开发领域,微服务架构已经成为了众多企业和开发者的首选。本文将深入探讨微服务架构的核心概念、优势以及实施过程中可能遇到的挑战。我们将从基础开始,逐步深入了解如何构建、部署和管理微服务。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的见解和实用的建议。
18 0
|
1月前
|
存储 缓存 测试技术
构建高效后端系统的关键策略##
【10月更文挑战第2天】 在当今数字化时代,后端系统的性能和可扩展性对于任何技术驱动的企业都至关重要。本文将深入探讨如何通过优化数据库设计、实施缓存机制、采用微服务架构以及自动化测试等措施,构建一个既高效又可靠的后端系统。我们将从基础的代码优化开始,逐步讨论到架构级别的改进,最终目标是提供一个全面的指导方案,帮助开发者和企业提升其后端系统的性能和可维护性。 ##
48 2
|
1月前
|
数据可视化 测试技术 Linux
基于Python后端构建多种不同的系统终端界面研究
【10月更文挑战第10天】本研究探讨了利用 Python 后端技术构建多样化系统终端界面的方法,涵盖命令行界面(CLI)、图形用户界面(GUI)及 Web 界面。通过分析各种界面的特点、适用场景及关键技术,展示了如何使用 Python 标准库和第三方库(如 `argparse`、`click`、`Tkinter` 和 `PyQt`)实现高效、灵活的界面设计。旨在提升用户体验并满足不同应用场景的需求。
|
12天前
|
JavaScript 前端开发 C#
从入门到放弃,我们为何从 Blazor 回到 Vue
【10月更文挑战第29天】在前端开发中,许多开发者从尝试新技术 Blazor 最终回到熟悉的 Vue。主要原因包括:1) Blazor 学习曲线陡峭,Vue 上手容易;2) Vue 开发工具成熟,开发效率高;3) Vue 性能优异,优化简单;4) Vue 社区庞大,生态丰富;5) 项目需求和团队协作更适配 Vue。选择技术栈需综合考虑多方面因素。
|
1月前
|
JavaScript 前端开发
vue3教程,如何手动获取后端数据(入门到精通3,新人必学篇)
本文提供了一个Vue 3教程,讲解了如何使用axios库手动从后端获取数据,包括安装axios、配置后端访问地址、编写路由地址、发起HTTP请求以及在组件中读取和打印响应数据的步骤。
234 0
vue3教程,如何手动获取后端数据(入门到精通3,新人必学篇)
|
27天前
|
前端开发 JavaScript 小程序
前端uni开发后端用PHP的圈子系统该 如何做源码?
圈子系统系统基于TP6+Uni-app框架开发;客户移动端采用uni-app开发,管理后台TH6开发。系统支持微信公众号端、微信小程序端、H5端、PC端多端账号同步,可快速打包生成APP