一、Controller
- 控制器的目的是接收应用的特定请求
import { Controller, Get } from '@nestjs/common';
@Controller('cats')
export class CatsController {
@Get()
findAll(): string {
return 'This action returns all cats';
}
}
二、Provider
- 控制器应处理 HTTP 请求并将更复杂的任务委托给 providers。Providers 是纯粹的 JavaScript 类,在其类声明之前带有
@Injectable()
装饰器。
import { Injectable } from '@nestjs/common';
import { Cat } from './interfaces/cat.interface';
@Injectable()
export class CatsService {
private readonly cats: Cat[] = [];
create(cat: Cat) {
this.cats.push(cat);
}
findAll(): Cat[] {
return this.cats;
}
}
三、Module
- 每个 Nest 应用程序至少有一个模块,即根模块。
在大多数情况下,您将拥有多个模块,每个模块都有一组紧密相关的功能。 -
providers
由 Nest 注入器实例化的提供者,并且可以至少在整个模块中共享
-
-
controllers
必须创建的一组控制器
-
-
imports
导入模块的列表,这些模块导出了此模块中所需提供者
-
-
exports
由本模块提供并应在其他模块中可用的提供者的子集。
-
import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';
@Module({
controllers: [CatsController],
providers: [CatsService],
})
export class CatsModule {}
四、中间件
- 中间件是在路由处理程序,之前,调用的函数
- 中间件不能在 @Module() 装饰器中列出。我们必须使用模块类的
configure()
方法来设置它们。包含中间件的模块必须实现 NestModule 接口。
// 声明
import { Injectable, NestMiddleware } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';
@Injectable()
export class LoggerMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: NextFunction) {
console.log('Request...');
next();
}
}
1.局部 应用中间件
// 应用中间件
import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware';
import { CatsModule } from './cats/cats.module';
@Module({
imports: [CatsModule],
})
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer
.apply(LoggerMiddleware)
.forRoutes('cats');
}
}
2.局部 函数式中间件
// 函数式中间件
export function logger(req, res, next) {
console.log(`Request...`);
next();
};
consumer
.apply(logger)
.forRoutes(CatsController);
3.全局中间件
// 全局中间件
const app = await NestFactory.create(AppModule);
app.use(logger);
await app.listen(3000);
五、过滤器
- 所有异常过滤器都应该实现通用的
ExceptionFilter<T>
接口。它需要你使用有效签名提供catch(exception: T, host: ArgumentsHost)
方法。T 表示异常的类型。
// 异常过滤器
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,
});
}
}
1.局部过滤器
// 局部过滤器 @UseFilters()
@Post()
@UseFilters(new HttpExceptionFilter())
async create(@Body() createCatDto: CreateCatDto) {
throw new ForbiddenException();
}
2.全局过滤器
// 全局过滤器 useGlobalFilters
async function bootstrap() {
const app = await NestFactory.create(AppModule);
const { httpAdapter } = app.get(HttpAdapterHost);
app.useGlobalFilters(new AllExceptionsFilter(httpAdapter));
await app.listen(3000);
}
bootstrap();
六、管道
- 必须提供
transform()
方法
import { PipeTransform, Injectable, ArgumentMetadata } from '@nestjs/common';
@Injectable()
export class ValidationPipe implements PipeTransform {
transform(value: any, metadata: ArgumentMetadata) {
return value;
}
}
- 绑定
@UsePipes()
@Post()
@UsePipes(new JoiValidationPipe(createCatSchema))
async create(@Body() createCatDto: CreateCatDto) {
this.catsService.create(createCatDto);
}
7、守卫
- 每个守卫必须实现一个
canActivate()
函数
// 声明
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Observable } from 'rxjs';
@Injectable()
export class AuthGuard implements CanActivate {
canActivate(
context: ExecutionContext,
): boolean | Promise<boolean> | Observable<boolean> {
const request = context.switchToHttp().getRequest();
return validateRequest(request);
}
}
// 绑定 @UseGuards()
@Controller('cats')
@UseGuards(RolesGuard)
export class CatsController {}
八、拦截器
- 每个拦截器都有
intercept()
方法,它接收2个参数。第一个是 ExecutionContext 实例(与守卫完全相同的对象)。
// 声明
import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
@Injectable()
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... ${Date.now() - now}ms`)),
);
}
}
// 绑定
@UseInterceptors(LoggingInterceptor)
export class CatsController {}
最后
文章为了方便个人学习梳理