管道与模块

管道

  1. 管道可以将输入数据转为所需的输出数据,此外还可以处理验证,数据错误时可能抛出异常;
  2. 创建管道
    nest g pipe pipe/news
    
    1. pipe/news.pipe.ts
    import { PipeTransform, Injectable, ArgumentMetadata } from '@nestjs/common'
    
    @Injectable
    export class NewsPipe implements PipeTransform {
        transform(value:any, metadata:ArgumentMetadata) {
            //value 一般就是 GET/POST 传递的数据
            return value
        }
    }
    
    1. 在控制器方法上使用
    import { UsePipes, Controller, Get, Query } from '@nestjs/common'
    import { NewsPipe } from '../pipe/news.pipe'
    
    @Controller('news')
    export class NewsController {
        @Get()
        @UsePipes(new NewsPipe())
        index(@Query() query) {
        }
    }
    
  3. 控制器接收到请求之后,会交给管道验证或处理这些数据,然后再交给控制器方法;
  4. 使用第三方库 joi 处理验证
    npm i @hapi/joi --save
    
    1. news.pipe.ts
        constructor(private readonly schema) {}
        transform(value:any, metadata:ArgumentMetadata) {
            // 根据Schema验证提交数据的合法性
            const { error } = this.schema.validate(value);
            if (error) {  //数据不合法,则抛出异常
                throw new BadRequestException('Validation failed');
            }
            return value;
        }
    
    1. 控制器
        import * as Joi from 'hapi/joi'
    
        //定义Schema
        let userSchema = Joi.object().keys({ 
            name:Joi.string().required(), 
            age:Joi.number().integer().min(6).max(66).required()
        });
        
        @Controller('news')
        export class NewsController {
            @Get()
            @UsePipes(new NewsPipe(userSchema))
            index(@Query() query) {
            }
        }
    
    1. 发起请求:http://localhost:3000/news?name=Mack&age=20

模块

  1. 模块是 @Module() 装饰的类,@Module()装饰器提供了元数据,Nest用模块来组织应用程序的结构;
  2. 通过脚手架创建项目时,会生成一个根模块:app.module.ts,根模块中可以挂载不同功能的子模块,而在子模块中挂载相应的控制器和服务;
  3. 创建模块:
    nest g module module/admin
    
    1. 生成admin模块:module/admin/admin.module.ts
    2. 在根模块中自动引入创建的子模块:
    import { AdminModule } from './module/admin/admin.module'
    @Module({
        imports: [AdminModule],
        controllers: [AppController],
        providers: [AppService]
    })
    export class AppModule {}
    
  4. 在子模块admin中创建控制器和服务
    1. 创建控制器
        nest g controller module/admin/controller/user
    
    1. 创建服务
        nest g service module/admin/service/user
    
    1. 因为admin模块已经存在了,所以控制器和服务会被自动挂载到子模块中,而不再挂载到根模块上;
        import { UserController } from './controller/user/user.controller';
        import { UserService } from './service/user/user.service';
        @Module({
            controllers: [UserController],
            providers: [UserService]
        })
        export class AdminModule {}
    
    1. 在控制器user.controller中引入服务,并依赖注入服务对象
        import { UserService } from '../../service/user/user.service';
        @Controller('admin/user')
        export class UserController {
            constructor(private userService:UserService) {}
    
            @Get()
            index() {
                return this.userService.findAll();
            }
        }
    
  5. 子模块中创建的服务默认是私有的,其他模块的控制器依赖注入时,也必须先挂载到对应的模块上,然后才能注入成功;
    import { NewsService } from '../api/news.service';
    @Module({
        controllers: [UserController],
        providers: [UserService, NewsService]
    })
    export class AdminModule {}
    
    import { NewsService } from '../../../api/news.service';
    @Controller('admin/user')
    export class UserController {
        // 同时注入UserService和NewsService两个服务
        constructor(private userService:UserService, private newsService:NewsService) {}
    
        @Get()
        index() {
            return this.userService.findAll();
        }
    
        @Get('news')
        index() {
            return this.newsService.getNews();
        }
    }
    
  6. 服务可以是公共的,模块也可以是公共的。把公共模块挂载到其他模块上之后,还需要在公共模块中导出服务,否则仍然不能使用!
    1. 公共模块
    import { UploadService } from './service/upload/upload.service';
    
    @Module({
        providers: [UploadService],  // 声明/挂载服务
        exports: [UploadService]  // 导出服务,引入share模块的模块中,可以使用导出服务
    })
    export class ShareModule {}
    
    1. 挂载公共模块
    //引入公共模块中的服务
    import { ShareModule } from '../share/share.module';
    @Module({
        imports: [ShareModule],  // 挂载公共模块
        controllers: [UserController],
        providers: [UserService, NewsService]
    })
    export class AdminModule {}
    
    1. 注入公共模块中的服务
    import { UploadService } from '../../../share/service/upload/upload.service';
    
    @Controller('admin/user')
    export class UserController {
        
        constructor(private userService:UserService, private uploadService:UploadService) {}
    
        @Get()
        index() {
            return this.userService.findAll();
        }
    
        @Get('upload')
        upload() {
            return this.uploadService.upload();
        }
    }
    

你可能感兴趣的:(管道与模块)