1. The clientClient Side

  • After the client sends a request, the sequence of processing flow is as follows
  • Accuracy cannot be guaranteed for the time being, further information is needed…
  • Summary of their own, need to improve the details later…

2. Abnormal filterFilter

  • The filter is processed after the client sends the request, favoring the client
  • Global exception filters are used by defaultHttpExceptionOr a subclass of it
  • If not, the system returns the information to the client500, Internet server errorThe error of
// @catch decorator and implement the ExceptionFilter interface
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({
        statusCode: status,
        timestamp: new Date().toISOString(),
        path: request.url,
      })
  }
}

// Use @usefilters (HttpExceptionFilter)
// Method scope, controller scope, global scope...
Copy the code

3. The middlewareMiddleware

  • Function that can access request and response objects
  • throughnext()Pass control to the next middleware function
  • NestMiddleware can be implemented through functions or classes
// class, using the @Injectable decorator and implementing the NestMiddleware interface
import { Injectable, NestMiddleware } from '@nestjs/common'
import { Request, Response } from 'express'

@Injectable(a)export class LoggerMiddleware implements NestMiddleware {
  use(req: Request, res: Response, next: Function) {
    console.log('Request... ')
    next()
  }
}
Copy the code
// Function mode
export function logger(req, res, next) {
  console.log(`Request... `)
  next()
}
Copy the code

4. The guardsGuards

  • Middleware logic behind, interceptor/pipe before execution
  • Determines whether a request should be processed by a controller, typically in permission and role scenarios
  • Compared to middleware (callnext()Mission accomplished), guards also need to watch upstream and downstream
// Implement the CanActivate interface with the @Injectable decorator
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common'
import { Observable } from 'rxjs'

@Injectable(a)export class RolesGuard implements CanActivate {
  canActivate(
    context: ExecutionContext,
  ): boolean | Promise<boolean> | Observable<boolean> {
    return true}}Use @Guards(RolesGuard)
Copy the code
  • The guard is already available, but there is no execution context
  • There should be some types of permissions that need to be accessed
  • Usually use@SetMetadata()Adding a controllermetadata
@Post(a)@SetMetadata('role'['admin'])
async creat(){... }Copy the code
// Implement a custom decorator
import { SetMetadata } from '@nestjs/common'

export const Roles = (. roles:string[]) = > SetMetadata('roles', roles)

/ / use
@Post(a)@Roles('admin')
async create(){... }Copy the code

5. The interceptorInterceptors

  • use@InjectableAdornment,Must beimplementationNestInterceptorinterface
  • Bind additional logic before and after function execution
  • Converts a function return value
  • The exception thrown by the conversion function
  • Extend the underlying function behavior
  • Rewrite a function completely based on specific conditions
import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common'
import { Observable } from 'rxjs'
import { tap } from 'rxjs/operators'
@Injectable(a)export class LoggingInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    console.log('Before... ')

    const now = Date.now()
    return next
      .handle()
      .pipe(
        tap(() = > console.log(`After... The ${Date.now() - now}ms`)))}}Use @useinterceptors (LoggingInterceptor)
Copy the code
// Convert null in all responses to ""
import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common'
import { Observable } from 'rxjs'
import { map } from 'rxjs/operators'

@Injectable(a)export class ExcludeNullInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    return next
      .handle()
      .pipe(map(value= > value === null ? ' ' : value ))
  }
}
Copy the code

6. The pipePipes

  • The controller receives the request before processing, biased towards the server
  • use@InjectableAdornment,Must beimplementationPipeTransforminterface
  • Convert input data to target format && validate input data
  • The pipe executes within the exception scope – the exception handling layer handles the pipe exception
  • built-inValidationPipeParseIntPipe
// Use with third-party libraries
// yarn add class-validator class-transformer
import { validate } from 'class-validator'
import { plainToClass } from 'class-transformer'

@Injectable(a)export class ValidationPipe implements PipeTransform<any> {
  async transform(value: any, { metatype }: ArgumentMetadata) {
    if(! metatype || !this.toValidate(metatype)) {
      return value;
    }
    const object = plainToClass(metatype, value)
    const errors = await validate(object)
    if (errors.length > 0) {
      throw new BadRequestException('Validation failed')}return value;
  }

  private toValidate(metatype: Function) :boolean {
    const types: Function[] = [String.Boolean.Number.Array.Object]
    return! types.includes(metatype) } }// Use @usepipes (ValidationPipe)
Copy the code

阿鲁纳恰尔邦

7. ControllerController

  • Process client requests and send response content
  • Routing determines which request (call) to processServiceTo deal with)
  • @controller () &&@get (), @post ()...
  • nest g controller cats
import { Controller, Get } from '@nestjs/common'

@Controller('cats')
export class CatsController {
  @Get(a)async findAll(): string {
    return 'This action returns all cats'}}Copy the code

Provider 8.Providers

  • Inversion of controlIOCIn the patternDependency injectionfeatures
  • use@Injectable()decoration

Services

  • Inject and reference into the controller
  • Usually only focused on processing business logic forControllercall
  • nest g service cats
import { Injectable } from '@nestjs/common';
import { Cat } from './interfaces/cat.interface';

@Injectable(a)export class CatsService {
  private readonly cats: Cat[] = [];

  create(cat: Cat) {
    this.cats.push(cat);
  }

  findAll(): Cat[] {
    return this.cats; }}// ./interfaces/cat.interface
export interface Cat {
	name: string
  age: number
  breed: string
}
Copy the code
// Inject the Service into the controller
import { CatsService } from './cats.service'
@Controller('cats')
export class CatsController {
  constructor(private readonly catsService: CatsService) {}

  @Get(a)async findAll(): Promise<Cat[]> {
    return this.catsService.findAll(); }}Copy the code

9. The moduleModule

  • Each application has at least one root module, which acts as the entry point to the application
  • use@Moduledecoration
  • nest g module cats
import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
  exports: [CatsService] // Export the share
})
export class CatsModule {}
Copy the code

Entrance 10.main.ts

async function bootstrap() {
	const app = await NestFactory.create(AppModule)
  
  // Global configuration can be added through app.use
  app.use(logger) // Global Logger middleware
  app.useGlobalFilters(new HttpExceptionFilter()) // Global exception filter
  app.useGlobalPipes(new ValidationPipe()) // Global pipe handling
  app.useGlobalGuards(new RolesGuards()) // Global guard
  app.useGlobalInterceptors(new LoggingInterceptor()) // Global interceptor
  
  await app.listen(3000)}Copy the code

The resources

  • Keelii.com/2019/07/03/…
  • Docs. Nestjs. Cn/seven/introduct…