• Nest.js 入门基础


    安装

    # 如果是 node.js 10 之后的版本,需要加 --ignore-engines 来忽略一些不兼容库的警告
    npm i -g @nestjs/cli --ignore-engines
    # 或
    yarn global add @nestjs/cli --ignore-engines
    
    • 1
    • 2
    • 3
    • 4

    入门文档

    小技巧

    异步方法优化

    减少不必要的 async/await 包裹。示例代码如下:

    function test() {
      const deferred = {
        promise: undefined,
        resolve: undefined
      };
      deferred.promise = new Promise((resolve) => {
        deferred.resolve = resolve;
      });
      setTimeout(() => {
        deferred.resolve('hello world');
      }, 1000);
      return deferred.promise;
    }
    
    @Controller()
    export class AppController {
      constructor(private readonly appService: AppService) {}
    
      // 以下两种写法都能运行,推荐使用第一种
      @Get('/test')
      getTest(): Promise<string> {
        return test();
      }
    
      @Get('/test2')
      async getTest2(): Promise<string> {
        return await test();
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    同理,除了在 Controller 中,在 Model、 Service 等其他地方内层方法均可以进行优化,因为外层调用的时候已经带上了 await。同时,还需要注意各个方法的返回类型,养成良好习惯。

    使用 Fastify 框架

    该部分没有文档,只有一个示例项目: https://github.com/nestjs/nest/tree/master/sample/10-fastify

    yarn remove @nestjs/platform-express
    yarn remove @types/express
    yarn add @nestjs/platform-fastify
    
    • 1
    • 2
    • 3

    修改 main.ts 文件:

    import { NestFactory } from '@nestjs/core';
    // 新增引用
    import {
      FastifyAdapter,
      NestFastifyApplication,
    } from '@nestjs/platform-fastify';
    import { AppModule } from './app.module';
    
    async function bootstrap() {
      // 原有代码:
      // const app = await NestFactory.create(AppModule);
      // 替换代码:
      const app = await NestFactory.create<NestFastifyApplication>(
        AppModule,
        new FastifyAdapter(),
      );
      await app.listen(3000);
      console.log(`Application is running on: ${await app.getUrl()}`);
    }
    bootstrap();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    Open-API(Swagger)

    目前只有英文文档,没有中文文档。地址:https://docs.nestjs.com/openapi/introduction

    配合 Fastify 使用:

    yarn add @nestjs/swagger
    yarn add fastify-swagger
    # [Nest] 7253   - 2020/07/08 下午4:42:59   [PackageLoader] The "fastify-swagger" package is missing. Please, make sure to install this library ($ npm install fastify-swagger) to take advantage of SwaggerModule. +37ms
    # 如果出现类似报错,使用2.x版本重试
    yarn add fastify-swagger@^2.6.0
    
    • 1
    • 2
    • 3
    • 4
    • 5

    示例代码:

    import { NestFactory } from '@nestjs/core';
    import {
      FastifyAdapter,
      NestFastifyApplication,
    } from '@nestjs/platform-fastify';
    import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
    import { AppModule } from './app.module';
    
    async function bootstrap() {
      const app = await NestFactory.create<NestFastifyApplication>(
        AppModule,
        new FastifyAdapter(),
      );
      const options = new DocumentBuilder()
        .setTitle('Cats example')
        .setDescription('The cats API description')
        .setVersion('1.0')
        .addTag('cats')
        .addBearerAuth()
        .build();
      // 生成的 JSON 格式文档,可以导出静态化
      const document = SwaggerModule.createDocument(app, options);
      // 注入, 访问 http://localhost:3000/api 可以访问
      SwaggerModule.setup('api', app, document);
    
      await app.listen(3000);
      console.log(`Application is running on: ${await app.getUrl()}`);
    }
    bootstrap();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    Module 代码可以参考 Express Swagger 的示例项目: https://github.com/nestjs/nest/tree/master/sample/11-swagger

    生成 Open-API.json 文件示例代码:

    import { resolve } from 'path';
    import { writeFileSync } from 'fs';
    
    import { NestFactory } from '@nestjs/core';
    import { FastifyAdapter, NestFastifyApplication } from '@nestjs/platform-fastify';
    import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
    import { AppModule } from './app.module';
    
    async function bootstrap() {
      const app = (await NestFactory.create) < NestFastifyApplication > (AppModule, new FastifyAdapter());
      const options = new DocumentBuilder()
        .setTitle('Cats example')
        .setDescription('The cats API description')
        .setVersion('1.0')
        .addTag('cats')
        .addBearerAuth()
        .build();
      // 生成的 JSON 格式文档,可以导出静态化
      const document = SwaggerModule.createDocument(app, options);
      writeFileSync(resolve(__dirname, '../api.json'), JSON.stringify(document, null, 2), { encoding: 'utf8' });
    }
    bootstrap();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    E2E Testing

    依然没有找到文档,参考一个示例的测试源码吧: https://github.com/nestjs/nest/blob/master/integration/hello-world/e2e/fastify-adapter.spec.ts

    import { Test, TestingModule } from '@nestjs/testing';
    import { AppModule } from './../src/app.module';
    // 新增引用
    import { FastifyAdapter, NestFastifyApplication } from '@nestjs/platform-fastify';
    import { expect } from 'chai';
    
    describe('AppController (e2e)', () => {
      let app: NestFastifyApplication;
    
      beforeEach(async () => {
        const moduleFixture: TestingModule = await Test.createTestingModule({
          imports: [AppModule]
        }).compile();
    
        // 修改 app 创建
        app = moduleFixture.createNestApplication < NestFastifyApplication > new FastifyAdapter();
    
        await app.init();
      });
    
      it('/ (GET)', () => {
        // return request(app.getHttpServer())
        //   .get('/')
        //   .expect(200)
        //   .expect('Hello World!');
    
        // 改用 inject 方式,不用 supertest
        return app
          .inject({
            method: 'GET',
            url: '/'
          })
          .then(({ payload }) => expect(payload).to.be.eql('Hello World!'));
      });
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    Logger

    npm i --save nestjs-pino
    npm i --save-dev pino-pretty
    
    • 1
    • 2

    main.ts 入口文件引入:

    import { Logger } from 'nestjs-pino';
    
    const app = await NestFactory.create(MyModule, { logger: false });
    app.useLogger(app.get(Logger));
    
    • 1
    • 2
    • 3
    • 4

    app.module.ts 文件引入:

    import { LoggerModule } from 'nestjs-pino';
    
    @Module({
      imports: [LoggerModule.forRoot()],
      controllers: [AppController],
      providers: [MyService]
    })
    class MyModule {}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    Controller 中使用示例:

    import { Logger } from 'nestjs-pino';
    
    @Controller()
    export class AppController {
      constructor(private readonly myService: MyService, private readonly logger: Logger) {}
    
      @Get()
      getHello(): string {
        // pass message
        this.logger.log('getHello()');
    
        // also we can pass context
        this.logger.log('getHello()', AppController.name);
    
        return `Hello ${this.myService.getWorld()}`;
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    或者使用 PinoLogger (推荐):

    // my.service.ts
    import { PinoLogger, InjectPinoLogger } from 'nestjs-pino';
    
    @Injectable()
    export class MyService {
      // regular injecting
      constructor(private readonly logger: PinoLogger) {}
    
      // regular injecting and set context
      constructor(private readonly logger: PinoLogger) {
        logger.setContext(MyService.name);
      }
    
      // inject and set context via `InjectPinoLogger`
      constructor(@InjectPinoLogger(MyService.name) private readonly logger: PinoLogger) {}
    
      getWorld(...params: any[]) {
        this.logger.info('getWorld(%o)', params);
        return 'World!';
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    启动脚本修改:

    nest start --watch | pino-pretty
    
    • 1

    Graphql

    依赖于apollo-server

  • 相关阅读:
    Windows客户端下pycharm配置跳板机连接内网服务器
    Spring MVC - 相关内容3
    C++(21):特殊工具与技术
    huffman编译码
    docker-comose安装失败解决
    分布式事务的背景
    回归预测 | MATLAB实现BO-BiLSTM贝叶斯优化双向长短期神经网络多输入单输出回归预测
    Mysql判断字段是否为NULL
    js中的函数嵌套和闭包
    移动安全规范 — 2 -蓝牙安全规范
  • 原文地址:https://blog.csdn.net/jslygwx/article/details/131871857