nest

90 阅读3分钟

1.nest 是什么

  • 可扩展的node服务器端应用程序的框架
  • Nest是一个平台无关的框架,Nest 默认支持两个 HTTP 平台:express 和 fastify

1 创建项目

npm install -g @nestjs/cli
nest new 项目名

image.png

有几个关键文件

  • app.controller.ts 路由的基本控制器
  • app.module.ts 根模块
  • app.service.ts 基本服务
  • main.ts 入口文件

1.创建一个模块

nest generate resource xxx

image.png

可以选择哪种风格代码,我们选择http的REST风格

然后在AppModule中引用

image.png image.png

auth 为我们访问的路径

2.基本概念

1.控制器Controller

控制器负责处理传入的请求并向客户端返回响应,使用@Controller()装饰器,可以制定路由前缀,就像上文的auth

image.png @Get()装饰器也可以制定特定的路径@Get('id')将为像GET /auth/id

nest提供@Req装饰器可以访问请求对象,还可以使用专门的装饰器获取特定对象@Query可以获取请求路径上的query 信息,具体的可以看官网

image.png

image.png

2.提供者providers

依赖注入,即不同对象之间可以建立引用关系。 使用构造器注入,让auth控制器可以使用auth服务类 image.png 有两种注入方式,构造器注入和属性注入,区别当使用的类没有继承其他类,优先使用构造器注入。 image.png 提供者service提供数据,与数据库做交互,控制器Controller使用该服务做消费

3.模块

模块是有@Module()装饰器的类,提供元数据,Nest使用元数据来组织应用程序的结构。根模块nest用于解析模块和提供者之间关系和依赖关系的内部数据结构。

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { AuthModule } from 'src/modules/auth/auth.module';

@Module({
  imports: [AuthModule],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
  • provides 在此模块共享
  • imports 导出模块
  • 模块可以通过 @Global 声明为全局的,这样它 exports 的 provider 就可以在各处使用了,不需要其他模块在imports

4.装饰器

Nest提供了参数装饰器 想上文介绍的@Res

5.中间件middleware

6.interceptor拦截器

7. Pipe管道

8. 异常过滤器

流式传输文件

集成prisam

1.进入项目安装prisma

pnpm install prisma --save-dev

然后创建新的 migration:

npx prisma migrate dev --name init

image.png

数据库就就有这两个表了

image.png 在NestJS 服务中使用 Prisma 客户端

 nest g service prisma --flat --no-spec
 nest g module  prisma

创建一个server和module公用模块,在其他的模块使用

@Injectable()
export class PrismaService extends PrismaClient implements OnModuleInit {
  async onModuleInit() {
    await this.$connect();
  }
}

先创建用户登录DTO(Data Transfer Objects)用户输入的对象,当前端传递参数的时候需要做验证,nest中提供了管道验证 先安装需要的依赖

 pnpm i --save class-validator class-transformer

在Dto中增加一些验证规则

import { IsNotEmpty, IsString, Length, NotContains } from 'class-validator';
export class CreateUserDto {
  @Length(4, 16, { message: '用户名长度4-16位' })
  @NotContains(' ', { message: '用户名不能包含空格' })
  @IsString({ message: '用户名必须为字符串' })
  @IsNotEmpty({ message: '用户名不能为空' })
  username: string;

  @Length(6, 16, { message: '密码长度4-16位' })
  @NotContains(' ', { message: '密码不能包含空格' })
  @IsString({ message: '密码必须为字符串' })
  @IsNotEmpty({ message: '密码不能为空' })
  password: string;
}

建立vo类,就是传递给前端的数据,其中password不需要传递给用户,所以用装饰器排除

import { Exclude } from 'class-transformer';

export class UserVo {
  id: number;
  username: string;
  nickName?: string;
  @Exclude()
  password: string;
  avatarUrl?: string;
  gender?: string;
  enabled: boolean;
}

在userService中用构造器注入prismaService,在数据库中做新增操作,使用plainToClass将数据转化为UserVo

export class UserService {
  constructor(private readonly prismaService: PrismaService) {}
  async create(createUserDto: CreateUserDto) {
    console.log(createUserDto);
    const hashedPassword = createUserDto.password;
    const user = await this.prismaService.user.create({
      data: {
        ...createUserDto,
        password: hashedPassword,
      },
    });

    const userVo = plainToClass(UserVo, user);

    return userVo;
  }

进行接口验证,上文我们进行了管道验证,用户名和密码做了一些规则校验

image.png 现在测试一下,当传入的值不符合规则的时候会进行报错

image.png

image.png 那我们怎么让报错信息

docker 配置数据库 postgresql

配置swager文档

认证授权

环境变量