Nest.js Getting Started Basics

Install

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

getting started document

Tips

Asynchronous method optimization

Reduce unnecessary async/await wrappers. The sample code is as follows:

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

In the same way, except in the Controller, the inner methods in Model, Service and other places can be optimized, because the outer layer has already brought it when calling await. At the same time, you also need to pay attention to the return type of each method and develop good habits.

Using the Fastify framework

There is no documentation for that part, just a sample project: https://github.com/nestjs/nest/tree/master/sample/10-fastify

yarn remove @nestjs/platform-express
yarn remove @types/express
yarn add @nestjs/platform-fastify

Modify main.tsthe file:

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

Open-API(Swagger)

Currently there are only English documents, no Chinese documents. Address: https://docs.nestjs.com/openapi/introduction

Use with 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

Sample code:

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

Module code can refer to the sample project of Express Swagger: https://github.com/nestjs/nest/tree/master/sample/11-swagger

Generate Open-API.json file sample code:

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

E2E Testing

Still haven't found the document, please refer to an example test source code: 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!'));
  });
});

Logger

npm i --save nestjs-pino
npm i --save-dev pino-pretty

The main.ts entry file imports:

import {
    
     Logger } from 'nestjs-pino';

const app = await NestFactory.create(MyModule, {
    
     logger: false });
app.useLogger(app.get(Logger));

The app.module.ts file introduces:

import {
    
     LoggerModule } from 'nestjs-pino';

@Module({
    
    
  imports: [LoggerModule.forRoot()],
  controllers: [AppController],
  providers: [MyService]
})
class MyModule {
    
    }

Example of usage in 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()}`;
  }
}

Or use PinoLogger(recommended):

// 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!';
  }
}

Startup script modification:

nest start --watch | pino-pretty

Graphql

depends on apollo-server.

Guess you like

Origin blog.csdn.net/jslygwx/article/details/131871857