管道
- 管道可以将输入数据转为所需的输出数据,此外还可以处理验证,数据错误时可能抛出异常;
- 创建管道
nest g pipe pipe/news
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 } }
- 在控制器方法上使用
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) { } }
- 控制器接收到请求之后,会交给管道验证或处理这些数据,然后再交给控制器方法;
- 使用第三方库
joi
处理验证npm i @hapi/joi --save
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; }
- 控制器
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) { } }
- 发起请求:
http://localhost:3000/news?name=Mack&age=20
模块
- 模块是
@Module()
装饰的类,@Module()
装饰器提供了元数据,Nest
用模块来组织应用程序的结构; - 通过脚手架创建项目时,会生成一个根模块:
app.module.ts
,根模块中可以挂载不同功能的子模块,而在子模块中挂载相应的控制器和服务; - 创建模块:
nest g module module/admin
- 生成
admin
模块:module/admin/admin.module.ts
- 在根模块中自动引入创建的子模块:
import { AdminModule } from './module/admin/admin.module' @Module({ imports: [AdminModule], controllers: [AppController], providers: [AppService] }) export class AppModule {}
- 生成
- 在子模块
admin
中创建控制器和服务- 创建控制器
nest g controller module/admin/controller/user
- 创建服务
nest g service module/admin/service/user
- 因为
admin
模块已经存在了,所以控制器和服务会被自动挂载到子模块中,而不再挂载到根模块上;
import { UserController } from './controller/user/user.controller'; import { UserService } from './service/user/user.service'; @Module({ controllers: [UserController], providers: [UserService] }) export class AdminModule {}
- 在控制器
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(); } }
- 子模块中创建的服务默认是私有的,其他模块的控制器依赖注入时,也必须先挂载到对应的模块上,然后才能注入成功;
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(); } }
- 服务可以是公共的,模块也可以是公共的。把公共模块挂载到其他模块上之后,还需要在公共模块中导出服务,否则仍然不能使用!
- 公共模块
import { UploadService } from './service/upload/upload.service'; @Module({ providers: [UploadService], // 声明/挂载服务 exports: [UploadService] // 导出服务,引入share模块的模块中,可以使用导出服务 }) export class ShareModule {}
- 挂载公共模块
//引入公共模块中的服务 import { ShareModule } from '../share/share.module'; @Module({ imports: [ShareModule], // 挂载公共模块 controllers: [UserController], providers: [UserService, NewsService] }) export class AdminModule {}
- 注入公共模块中的服务
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(); } }
网友评论