十三、app的一些补充(nestjs+next.js从零开始一步一步创建通用后台管理系统)

45 阅读2分钟

1、配置文件补遗

在第三章我们介绍了配置文件的使用方式,我们使用一次性取出一组配置项的方式修改main.ts中一些固定值。

1) 每组配置项设置一个配置文件(当然你也可以在一个配置文件中把所有项都配置上)。

//app.config.ts
import { registerAs } from '@nestjs/config';

export default registerAs('appConfig', () => ({
  app:{
    port: process.env.APP_PORT||8000,
    prefix: process.env.APP_PREFIX||'/api'
  },
  // 其他配置项
}));

//db.config.ts
import { registerAs } from '@nestjs/config';

export default registerAs('dbConfig', () => ({
  database: {
    type: process.env.DB_TYPE||'mysql',
    host: process.env.DB_HOST||'localhost',
    port: process.env.DB_PORT||3306,
    username: process.env.DB_USERNAME||'root',
    password: process.env.DB_PASSWORD||'',
    database: process.env.DB_NAME||'test',
    charset: process.env.DB_CHARSET||'utf8mb4',
  },
}));

//swagger.config.ts
import { registerAs } from '@nestjs/config';
export default registerAs('swaggerConfig', () => ({
  swagger:{
    enable:process.env.SWAGGER_ENABLE||true,
    title: process.env.SWAGGER_TITLE||'接口文档',
    description: process.env.SWAGGER_DESCRIPTION||'后台管理系统接口文档',
    version:process.env.SWAGGER_VERSION||'1.0',
    url:process.env.SWAGGER_URL||'/doc'
  },
  // 其他配置项
}));

2) 修改api前缀及端口号

//main.ts
//注入配置服务
const configService = app.get(ConfigService);
// 设置 api 访问前缀
const appConfig = configService.get('appConfig.app');
app.setGlobalPrefix(appConfig.prefix);
...
//设置api访问端口
await app.listen(appConfig.port);

3) 修改swagger配置

增加swagger开启开关,设置swagger访问地址为前缀+swagger地址,如/api/doc。

//swagger配置 start
  const swaggerConfig=configService.get('swaggerConfig.swagger');
  if (swaggerConfig.enable) {
    const title=swaggerConfig.title;
    const description=swaggerConfig.description;
    const version=swaggerConfig.version;
    const url=appConfig.prefix+swaggerConfig.url;///api/doc

    const options = new DocumentBuilder()
    .setTitle(title) // 标题
    .setDescription(description) // 描述
    .setVersion(version) // 版本
    .addBearerAuth()
    .addTag('NestJS')
    .build();

    const document = SwaggerModule.createDocument(app, options);

    SwaggerModule.setup(url, app, document);
  }
  //swagger配置 end

4) 配置文件如下

//.env
# 应用配置
API_PREFIX=/api
APP_PORT=8000

# swagger配置
SWAGGER_ENABLED=true
SWAGGER_TITLE='接口文档'
SWAGGER_DESCRIPTION='后台管理系统接口文档'
SWAGGER_VERSION='1.0'
SWAGGER_URL='/doc'

# 数据库配置
DB_TYPE=mysql
DB_HOST=localhost
DB_PORT=3306
DB_USERNAME=root
DB_PASSWORD=root
DB_NAME=test
DB_CHARSET=utf8mb4

2、开启跨域访问

前后端分离程序在访问后台api时往往因为端口号问题导致跨域访问,造成拒绝服务,一般后端api会开启跨域访问: 方式1:

const app = await NestFactory.create(AppModule, {
    // 设置允许跨域
    cors: true,
    logger: ['error', 'warn'],
  });

方式2:

app.enableCors();

3、使用中间件记录接口访问日志

配置中间件记录访问接口的ip、参数等信息。

import { Inject, Injectable, NestMiddleware } from '@nestjs/common';
import { NextFunction, Request, Response } from 'express';
import { Logger } from 'src/common/logger/logger';

@Injectable()
export class LoggerMiddleware implements NestMiddleware {
  @Inject(Logger)
  private logger: Logger
  use(req: Request, res: Response, next: NextFunction) {
    const statusCode = res.statusCode;
    const logFormat = `
######################################
RequestOriginal: ${req.originalUrl}
Method: ${req.method}
IP: ${req.ip}
StatusCode: ${statusCode}
Params: ${JSON.stringify(req.params)}
Query: ${JSON.stringify(req.query)}
Body: ${JSON.stringify(req.body)}
#######################################
`;

    next();
    
    if (statusCode >= 500) {
      this.logger.error(logFormat, 'Request LoggerMiddleware');
    } else if (statusCode >= 400) {
      this.logger.warn(logFormat, 'Request LoggerMiddleware');
    } else {
      this.logger.log(logFormat, 'Request LoggerMiddleware');
    }
  }
}

在app.module中启用中间件:

//export class AppModule {} 改行修改为下面代码,启用中间件
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer.apply(LoggerMiddleware).forRoutes('*');
  }
}

测试:在浏览器中访问一个接口,如http://localhost:8000/api/user,控制台得到如下输出:

image.png