create-chuntianxiaozhu
Version:
春天小猪模板工具
689 lines (536 loc) • 14.2 kB
Markdown
# 控制器
初始化控制器
```bash
nest g controller [控制器名]
```
## 请求
一个请求包括请求方式,请求头,请求内容,请求参数,响应头,响应内容
```ts
// @Get()
// @Post()
// @Put()
// @Delete()
// @Patch()
// @Options()
// @Head()
// @All()
import {
Controller,
Get,
Query,
Post,
Body,
Put,
Param,
Delete,
} from '@nestjs/common';
import { CreateCatDto, UpdateCatDto, ListAllEntities } from './dto';
export class CatsController {
create( createCatDto: CreateCatDto) {
return 'This action adds a new cat';
}
findAll( query: ListAllEntities) {
return `This action returns all cats (limit: ${query.limit} items)`;
}
findOne( id: string) {
return `This action returns a #${id} cat`;
}
update( id: string, updateCatDto: UpdateCatDto) {
return `This action updates a #${id} cat`;
}
remove( id: string) {
return `This action removes a #${id} cat`;
}
}
```
# 服务
服务负责数据存储和检索
nest g service [模块名]
```ts
import { Injectable } from '@nestjs/common';
import { Cat } from './interfaces/cat.interface';
export class CatsService {
private readonly cats: Cat[] = [];
create(cat: Cat) {
this.cats.push(cat);
}
findAll(): Cat[] {
return this.cats;
}
}
// 在控制器中使用
import { Controller, Get, Post, Body } from '@nestjs/common';
import { CreateCatDto } from './dto/create-cat.dto';
import { CatsService } from './cats.service';
import { Cat } from './interfaces/cat.interface';
export class CatsController {
constructor(private catsService: CatsService) {}
async create( createCatDto: CreateCatDto) {
this.catsService.create(createCatDto);
}
async findAll(): Promise<Cat[]> {
return this.catsService.findAll();
}
}
```
# 模块
每个应用程序至少有一个模块,即根模块
nest g module [模块名]
```ts
import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';
export class CatsModule {}
```
装饰器使模块具有全局范围
# 中间件
可以在函数或带有装饰器的类中实现自定义 Nest 中间件。类应该实现NestMiddleware接口,而函数没有任何特殊要求。让我们首先使用类方法实现一个简单的中间件功能。
```ts
import { Injectable, NestMiddleware } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';
export class LoggerMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: NextFunction) {
console.log('Request...');
next();
}
}
```
注入中间件
```ts
import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { LoggerMiddleware } from './common/middleware/logger.middleware';
import { CatsModule } from './cats/cats.module';
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer.apply(LoggerMiddleware).forRoutes('cats');
}
}
```
或者全局中间件
```ts
app.use(logger);
```
# 异常过滤器
```ts
import {
ExceptionFilter,
Catch,
ArgumentsHost,
HttpException,
} from '@nestjs/common';
import { Request, Response } from 'express';
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,
});
}
}
```
绑定过滤器
```ts
async create( createCatDto: CreateCatDto) {
throw new ForbiddenException();
}
```
全局过滤器
```ts
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useGlobalFilters(new HttpExceptionFilter());
await app.listen(3000);
}
bootstrap();
```
扩展 的方法范围和控制器范围的过滤器BaseExceptionFilter不应使用 实例化new。相反,让框架自动实例化它们
```ts
import { Catch, ArgumentsHost } from '@nestjs/common';
import { BaseExceptionFilter } from '@nestjs/core';
export class AllExceptionsFilter extends BaseExceptionFilter {
catch(exception: unknown, host: ArgumentsHost) {
super.catch(exception, host);
}
}
```
# 管道
转换:将输入数据转换为所需的形式(例如,从字符串到整数)
验证:评估输入数据,如果有效,则简单地通过不变;否则,抛出异常
一个常用的类dto验证器
```ts
// 管道数据验证器
import {
ArgumentMetadata,
BadRequestException,
Injectable,
PipeTransform,
} from '@nestjs/common';
import { plainToInstance } from 'class-transformer';
import { validate } from 'class-validator';
export class ValidationPipe implements PipeTransform<any> {
async transform(value: any, metadata: ArgumentMetadata) {
const { metatype } = metadata;
if (!metatype || !this.toValidate(metatype)) {
return value;
}
const object = plainToInstance(metatype, value);
const errors = await validate(object);
if (errors.length > 0) {
throw new BadRequestException('参数校验失败');
}
return value;
}
private toValidate(metatype: Function): boolean {
const types: Function[] = [String, Boolean, Number, Array, Object];
return !types.includes(metatype);
}
}
// 注册全局管道
app.useGlobalPipes(new ValidationPipe());
// 创建具有校验的dto
import { IsNotEmpty, IsString } from 'class-validator';
export class CommonDto {
name: string;
}
```
# 卫兵
守卫是一个用装饰器注释的类,它实现了CanActivate接口
警卫的职责单一。它们根据运行时存在的某些条件(如权限、角色、ACL 等)确定路由处理程序是否处理给定的请求。这通常称为授权
卫兵在所有中间件之后、任何拦截器或管道之前执行
比如权限验证
```ts
// 定义卫兵
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Observable } from 'rxjs';
export class AuthGuard implements CanActivate {
canActivate(
context: ExecutionContext,
): boolean | Promise<boolean> | Observable<boolean> {
const request = context.switchToHttp().getRequest();
return !!request;
}
}
// 在控制器中使用卫兵
// 全局使用卫兵
app.useGlobalGuards(new RolesGuard());
```
## 权限元数据
```ts
// 定义接口角色
async create( createCatDto: CreateCatDto) {
this.catsService.create(createCatDto);
}
// 改进装饰器
import { SetMetadata } from '@nestjs/common';
export const Roles = (...roles: string[]) => SetMetadata('roles', roles);
async create( createCatDto: CreateCatDto) {
this.catsService.create(createCatDto);
}
// 在卫兵中进行鉴权
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
export class RolesGuard implements CanActivate {
constructor(private reflector: Reflector) {}
canActivate(context: ExecutionContext): boolean {
const roles = this.reflector.get<string[]>('roles', context.getHandler());
if (!roles) {
return true;
}
const request = context.switchToHttp().getRequest();
const user = request.user;
return matchRoles(roles, user.roles);
}
}
```
# 拦截器
拦截器是用装饰器注释并实现接口的类NestInterceptor
拦截器具有一组有用的功能,这些功能受到面向方面编程(AOP) 技术的启发
- 在方法执行之前/之后绑定额外的逻辑
- 转换函数返回的结果
- 转换函数抛出的异常
- 扩展基本功能行为
- 根据特定条件完全覆盖函数(例如,出于缓存目的)
# 缓存
```bash
yarn add /cache-manager cache-manager
```
```ts
// 在指定模块中使用缓存
import { Module } from '@nestjs/common';
import { CacheModule } from '@nestjs/cache-manager';
import { AppController } from './app.controller';
export class AppModule {}
// 缓存使用
constructor( private cacheManager: Cache) {}
```
# 序列化
用于转换和清理要返回给客户端的数据的规则,例如,密码等敏感数据应始终从响应中排除。
```ts
import { Exclude } from 'class-transformer';
export class UserEntity {
id: number;
firstName: string;
lastName: string;
password: string;
constructor(partial: Partial<UserEntity>) {
Object.assign(this, partial);
}
}
```
请注意,我们必须返回该类的一个实例。如果您返回纯 JavaScript 对象,例如 ,{ user: new UserEntity() }则该对象将无法正确序列化。
提供别名
```ts
get fullName(): string {
return `${this.firstName} ${this.lastName}`;
}
```
# 任务调度
```bash
yarn add --save /schedule
yarn add -D /cron
```
```ts
import { Module } from '@nestjs/common';
import { ScheduleModule } from '@nestjs/schedule';
export class AppModule {}
```
该.forRoot()调用初始化调度程序并注册应用程序中存在的任何声明性cron 作业、超时和间隔。当生命周期挂钩发生时,就会进行注册onApplicationBootstrap,确保所有模块都已加载并声明任何计划的作业。
示例
```ts
import { Injectable, Logger } from '@nestjs/common';
import { Cron } from '@nestjs/schedule';
export class TasksService {
private readonly logger = new Logger(TasksService.name);
handleCron() {
this.logger.debug('Called when the current second is 45');
}
}
```
# 限流
# 日志
```ts
// 开启日志
const app = await NestFactory.create(AppModule, {
logger: ['error', 'warn'],
});
await app.listen(3000);
export class AppController {
private readonly logger = new Logger(AppController.name);
constructor(private readonly appService: AppService) {}
getHello(): string {
return this.appService.getHello();
}
test( commonDto: CommonDto): string {
console.log(commonDto.name);
this.logger.warn('测试内容');
return '测试';
}
}
```
# cookie
cookie解析器
```bash
yarn add cookie-parser
yarn add -D /cookie-parser
```
中间件
```ts
import * as cookieParser from 'cookie-parser';
app.use(cookieParser());
```
获取cookie
```ts
findAll( request: Request) {
console.log(request.cookies); // or "request.cookies['cookieKey']"
// or console.log(request.signedCookies);
}
```
设置cookie
```ts
findAll( response: Response) {
response.cookie('key', 'value')
}
```
# 文件上传
```bash
yarn add -D /multer
```
```ts
uploadFile( file: Express.Multer.File) {
console.log(file);
}
```
## 文件验证
```ts
import { PipeTransform, Injectable, ArgumentMetadata } from '@nestjs/common';
export class FileSizeValidationPipe implements PipeTransform {
transform(value: any, metadata: ArgumentMetadata) {
const oneKb = 1000;
return value.size < oneKb;
}
}
```
# 流媒体文件
有时您可能希望将文件从 REST API 发送回客户端。要使用 Nest 执行此操作,通常您需要执行以下操作。
```ts
export class FileController {
getFile( res: Response) {
const file = createReadStream(join(process.cwd(), 'package.json'));
file.pipe(res);
}
}
```
# 静态资源
```bash
yarn add hbs
```
使用了hbs(Handlebars)引擎
```ts
import { NestFactory } from '@nestjs/core';
import { NestExpressApplication } from '@nestjs/platform-express';
import { join } from 'path';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create<NestExpressApplication>(AppModule);
app.useStaticAssets(join(__dirname, '..', 'public'));
app.setBaseViewsDir(join(__dirname, '..', 'views'));
app.setViewEngine('hbs');
await app.listen(3000);
}
bootstrap();
```
模板渲染
```html
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>App</title>
</head>
<body>
{{ message }}
</body>
</html>
```
渲染控制层
```ts
import { Get, Controller, Render } from '@nestjs/common';
export class AppController {
root() {
return { message: 'Hello world!' };
}
}
```
# 安全
helmet
增加头安全
# 限流
```bash
yarn add /throttler
```
```ts
export class AppModule {}
```
定制
```ts
export class UsersController {}
export class UsersController {
// Rate limiting is applied to this route.
dontSkip() {
return "List users work with Rate limiting.";
}
// This route will skip rate limiting.
doSkip() {
return "List users work without Rate limiting.";
}
}
findAll() {
return "List users works with custom rate limiting.";
}
```
保护策略
```ts
export class ThrottleIpBodyGuard extends ThrottlerGuard {
getTracker(req: Request) {
return req.ip + req.body.username;
}
}
```