天天看點

NestJs + TypeOrm + Ant Design Pro 搭建股票估值查詢系統(一)

傳送門

  • 線上示範 賬号:guest ,密碼:123456
  • 源碼位址

本章内容

  1. Nest安裝與錯誤處理
  2. 自定義資料傳回格式
  3. 自定義異常處理、錯誤碼

安裝

請確定作業系統上安裝了 Node.js(>= 10.13.0)

本地環境

$ node -v
v14.15.4
$ npm -v
6.14.11
           

安裝Nest CLI

$ npm i -g @nestjs/cli 
           

初始化項目

$ nest new project-name
           

将建立

project-name

目錄, 安裝node子產品和一些其他樣闆檔案,并将建立一個

src

目錄,目錄中包含幾個核心檔案

src
├── app.controller.ts
├── app.module.ts
└── main.ts
           

運作項目

$ npm run start
           

神奇的事情發生了,迎面就是一堆錯誤

NestJs + TypeOrm + Ant Design Pro 搭建股票估值查詢系統(一)

遇到錯誤不要慌,交友網站搜一搜:

./node_modules/tapable

,喲呵,還是熱乎的

NestJs + TypeOrm + Ant Design Pro 搭建股票估值查詢系統(一)

大意是

tapable

這個庫更新了,相關

webpack

版本也更新了,吧啦吧…好歹找到了解決方案(原文連結:github)

NestJs + TypeOrm + Ant Design Pro 搭建股票估值查詢系統(一)

指令走一個

$ npm i @types/[email protected]
$ npm i [email protected]
           

再次運作啟動成功,浏覽器中輸入:

http://localhost:3000/

NestJs + TypeOrm + Ant Design Pro 搭建股票估值查詢系統(一)

久違的

hello world!

迷人依舊!

使用者子產品

不管業務需求是啥,先來個使用者子產品錯不了,

src

目錄下建立檔案夾

modules

,使用Nest CLI生成一個

user

子產品,控制器以及

service

$ nest g mo modules/user
$ nest g co modules/user
$ nest g s modules/user
           

user.controller.ts

寫入如下代碼

import { Controller, Get } from '@nestjs/common';

@Controller('user')
export class UserController {
  @Get('sayhi')
  async sayhi(): Promise<string> {
    return '你好,世界';
  }
}
           

重新運作項目,使用api調試工具通路:

http://localhost:3000/user/sayhi

,符合我們的預期

NestJs + TypeOrm + Ant Design Pro 搭建股票估值查詢系統(一)

資料格式

實際項目中,api接口傳回的一般都是固定結構的

json

對象,類似

{
    "code":0,
    "msg":"success",
    "data":{
			...
    }
}
           

其中

code

為自定義的業務錯誤碼,比如沒有權限,注冊時使用者名已注冊等,

src

目錄下建立

libs

檔案夾,建立一個攔截器

$ nest g in libs/interceptors/data
           

攔截器代碼

import {
  Injectable,
  NestInterceptor,
  CallHandler,
  ExecutionContext,
} from '@nestjs/common';
import { map } from 'rxjs/operators';
import { Observable } from 'rxjs';
interface Response<T> {
  data: T;
}
@Injectable()
export class TransformInterceptor<T>
  implements NestInterceptor<T, Response<T>> {
  intercept(
    context: ExecutionContext,
    next: CallHandler<T>,
  ): Observable<Response<T>> {
    return next.handle().pipe(
      map((data) => {
        return {
          data: data ?? null,
          code: 0,
          message: 'success',
        };
      }),
    );
  }
}
           

main.ts

中全局注冊

import { NestFactory } from '@nestjs/core';
import { TransformInterceptor } from './libs/interceptors/data.interceptor';
import { AppModule } from './app.module';

async function bootstrap() {
  ...
  app.useGlobalInterceptors(new TransformInterceptor());
  ...
}
bootstrap();
           

運作程式,再次通路:

http://localhost:3000/user/sayhi

{
    "data": "你好,世界",
    "code": 0,
    "message": "success"
}
           

自定義異常

實際項目中,很多情況下我們需要中斷程式運作,傳回錯誤資訊,建立一個過濾器

$ nest g f libs/filters/http-exception
           

src/libs

目錄下建立

enums

目錄,建立

error-code-enum.ts

檔案,放幾個錯誤碼

export enum BusiErrorCode {
  TIMEOUT = -1, // 系統繁忙
  SUCCESS = 0, // 成功
  PARAM_ERROR = 10000, // 請求參數錯誤
  NOT_FOUND = 10001, // 查找的資源不存在
  UN_AUTHORIZED = 20000, // 使用者未登入
  AUTH_FORBIDDEN = 30000, // 使用者沒有權限
  PWD_ERROR = 40000, // 賬号或者密碼錯誤
}
           

libs/filters

目錄下建立

busi.exception.ts

檔案

import { HttpException, HttpStatus } from '@nestjs/common';
import { BusiErrorCode } from '../enums/error-code-enum';

export class BusiException extends HttpException {
  private _code: BusiErrorCode;
  private _message: string;
  constructor(
    code: BusiErrorCode | number,
    message: string,
    statusCode: HttpStatus = HttpStatus.BAD_REQUEST,
  ) {
    super(message, statusCode);
    this._code = code;
    this._message = message;
  }

  getErrorCode(): BusiErrorCode {
    return this._code;
  }

  getErrorMessage(): string {
    return this._message;
  }
}
           

http-exception.filter.ts

檔案中代碼

import {
  ArgumentsHost,
  Catch,
  ExceptionFilter,
  HttpException,
} from '@nestjs/common';
import { BusiException } from './busi.exception';

@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();

    let code, message;
    if (exception instanceof BusiException) {
      code = exception.getErrorCode();
      message = exception.getErrorMessage();
    } else {
      code = exception.getStatus();
      message = exception.message;
    }
    response.status(status).json({
      code,
      message,
      data: null,
      date: new Date().toLocaleDateString(),
      path: request.url,
    });
  }
}
           

main.ts

中全局注冊

import { NestFactory } from '@nestjs/core';
import { TransformInterceptor } from './libs/interceptors/data.interceptor';
import { AppModule } from './app.module';

async function bootstrap() {
  ...
  app.useGlobalFilters(new HttpExceptionFilter());
  ...
}
bootstrap();
           

修改

user.controller.ts

,加入觸發異常的代碼

import { Controller, Get, HttpStatus } from '@nestjs/common';
import { BusiException } from '../../libs/filters/busi.exception';
import { BusiErrorCode } from '../../libs/enums/error-code-enum';

@Controller('user')
export class UserController {
  ...
  @Get('exception')
  async exception(): Promise<string> {
    // throw new BusiException(BusiErrorCode.NOT_FOUND, '預設狀态碼,預設觸發http 400錯誤');
    throw new BusiException(
      BusiErrorCode.NOT_FOUND,
      '錯誤:http狀态正常',
      HttpStatus.OK,
    );
  }
}
           

運作程式,通路:

http://localhost:3000/user/exception

NestJs + TypeOrm + Ant Design Pro 搭建股票估值查詢系統(一)

看起來還不錯,下篇我們搗鼓TypeOrm和MySQL資料庫。

繼續閱讀