preface


This is a word that anyone who has ever played Linux will know, for example:



Git’s commit record is displayed as a single line, and the commit profile has the word build



The pipe in NEST is mainly used to intercept and convert the input data type.

It is similar to the concept provided by NG





rendering

In actual combat

In fact, the official tutorial is quite good, both local pipes and global pipes are written, here we use the more general global pipe as an example, try to write more close to the business and more vulgar explanation

The installation

# class-validator: provides very rich type decorators
Class-transformer: convert regular data into classes quickly
# https://www.npmjs.com/package/class-validator
# https://www.npmjs.com/package/class-transformer
yarn add class-validator class-transformer
Copy the code

Seal the input intercept pipe

Usage: nest <command> [options]

Options:
  -v, --version                                   Output the current version.
  -h, --help                                      Output usage information.

Commands:
  new|n [options] [name]                          Generate Nest application.
  build [options] [app]                           Build Nest application.
  start [options] [app]                           Run Nest application.
  info|i                                          Display Nest project details.
  update|u [options]                              Update Nest dependencies.
  add [options] <library>                         Adds support foran external library to your project. generate|g [options] <schematic> [name] [path] Generate a Nest element. Available Schematics, ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┬ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┬ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ � � � ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ │ name │alias│ description │ application │ application │ Generate a new application workspace │ class │ cl │ Generate a new class │ │ configuration │ config │ Generate a CLI configuration file │ controller │ co │ Generate a controller declaration │ │ Generate a custom decorator │ │ filter │ f │ Generate a filter declaration │ gateway │ ga │ Generate a gateway declaration │ guard │ gu │ Generate a guard declaration │ interceptor │in│ Generate an interceptor declaration │ interface │ interface │ Generate an interface │ middleware │ mi │ Generate a Middleware declaration │ │ module │ mo │ Generate a module declaration │ pipe │ PI │ Generate a pipe declaration │ Provider │ pr │ Generate a provider declaration │ resolver │ r │ Generate a GraphQL resolver declaration │ service │ S │ Generate a service declaration │ library │ lib │ Generate a new library within a monorepo │ sub-app │ app │ Generate a new application within a monorepo │ resource │ res │ Generate a new CRUD resourceCopy the code
Validation.pipe. ts will be generated in SRC /common/ Pipes /
# Root path in nest-cli.json configuration! The default is SRC as the development root

nest n pi common/pipes/validation

Copy the code

Pipeline implementation

// src/pipe/validation.pipe.ts
import {
  ArgumentMetadata,
  BadRequestException,
  Injectable,
  PipeTransform,
} from '@nestjs/common';
// plainToClass converts a plain JS object to an instance of the specified class
import { plainToClass } from 'class-transformer';
Validator data can be recognized
import { validate } from 'class-validator';

Injectable();
export class ValidationPipe implements PipeTransform {
  // Value is the actual data passed in
  // Metatype is metadata, which is what the decorator adds
  async transform(value: any, { metatype }: ArgumentMetadata) {
    if(! metatype || !this.toValidate(metatype)) {
      // If no validation rule is passed in, data is returned without validation
      return value;
    }
    // Convert the object to Class for verification
    const object = plainToClass(metatype, value);
    // Synchronize block, return check result
    const errors = await validate(object);
    if (errors.length > 0) {
      // Just take the first error message and return it
      const msg = Object.values(errors[0].constraints)[0]; 
      // Throw this exception, and the logic will deliver nest's error interception
      // To intercept this error for processing, start with filters, as discussed later
      throw new BadRequestException('field verification failed:${msg}`);
    }
    return value;
  }
  // The purpose of this function is to verify that the type of metadata passed in is normal data in the definition
  private toValidate(metatype: any) :boolean {
    const types: any[] = [String.Boolean.Number.Array.Object];
    return !types.includes(metatype);
  }
}

Copy the code

configuration

The main entrance (main. Ts)

import { AppModule } from './app.module';
import { NestFactory } from '@nestjs/core';
import { ValidationPipe } from './common/pipes/validataion.pipe';
async function bootstrap() {
  const app = await NestFactory.create(AppModule, {
    cors: false.logger: false});// Set the global pipe
  app.useGlobalPipes(new ValidationPipe());

  await app.listen(configService.get('SERVE_LISTENER_PORT'));
}
bootstrap()

Copy the code

DTO annotations

import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import {
  IsInt,
  IsNumberString,
  IsOptional,
  IsString,
  Max,
  Min,
} from 'class-validator';

export enum UserRole {
  Boss = 'back door',
  Admin = 'Administrator',
  User = 'Regular user',}export class CreateAppDto {
  @ApiProperty({ enum: ['Boss'.'Admin'.'User']})role: UserRole;

  @IsOptional(a)@IsString({
    message: 'Username must be a string',})@ApiPropertyOptional({
    description: 'name',})readonlyname? :string;

  @IsInt(a)@Min(10, { message: 'Minimum age 10' })
  @Max(130, { message: 'Upper age limit 130' })
  @ApiProperty({
    description: 'age'.minimum: 0.maximum: 130.required: false,})readonly age: number;

  @IsString({
    message: 'Hobby must be string',})@ApiPropertyOptional({
    description: 'hobby',})readonly hobit: string;
}

export class FindOneParams {
  @IsNumberString(a)id: number;
}
Copy the code

Controller

import { Controller, Get, Post, HttpCode, Body, Query } from '@nestjs/common';
import {
  ApiCreatedResponse,
  ApiHeader,
  ApiInternalServerErrorResponse,
  ApiOkResponse,
  ApiOperation,
  ApiParam,
  ApiQuery,
  ApiResponse,
} from '@nestjs/swagger';
import { CreateAppDto, FindOneParams, UserRole } from './app.dto';
import { AppService } from './app.service';

@Controller(a)export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get()
  getHello(): string {
    return this.appService.getHello();
  }

  @ApiHeader({
    name: 'Authorization'.description: 'Auth token',})@ApiCreatedResponse({
    description: 'Link was successfully created, which is a description of the 201 state.',})@Post('/post')
  @HttpCode(200)
  @ApiParam({ name: 'name'.description: 'name'.type: CreateAppDto })
  postParams(@Body() param: CreateAppDto): string {
    return 'Test parameters' + JSON.stringify(param);
  }

  @Get('/user')
  @ApiOperation({
    tags: ['Get user information'].description: 'Get user information'.deprecated: true,})@ApiQuery({ name: 'id'.description: 'user id' })
  @ApiResponse({ description: 'Successfully requested back, which is essentially the description of 200.'.status: 200 })
  @ApiInternalServerErrorResponse({ description: 'Server exception' })
  updateApp(@Query() query: FindOneParams) {
    return JSON.stringify(query);
  }

  @Get('/netease-news/:id')
  @ApiOkResponse({ description: 'Successful request returned' })
  @ApiQuery({ name: 'id'.description: 'user id'.required: false })
  async async(@Body() body) {
    const res = await this.appService.getNetEaseNew(
      'https://anapioficeandfire.com/api/characters/583',
      { data: body },
    );
    return res.data;
  }

  @ApiQuery({ name: 'role'.enum: UserRole })
  @ApiOperation({
    tags: ['Return role information'].description: 'Return role information',})@Get('/role')
  async filterByRole(@Query('role') role: UserRole = UserRole.User) {
    returnrole; }}Copy the code

conclusion

Have wrong place please leave a message, will correct in time! Thanks for reading ~