本文主要是介绍Nest.js项目小结1,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
整体项目结构
prisma\ (用于管理数据库迁移、定义数据模型和数据填充)
migrations\ (日志记录,不用管)
schema.prisma (定义数据模型)
seed.ts (用于填充数据库初始数据的文件)
src\
auth\ (包含处理用户认证的模块代码)
dto\ (定义数据传输对象)
register.dto.ts (数据对象)
auth.controller.ts (处理路由等)
auth.module.ts (模块)
auth.service.ts (逻辑)
common\ (包含通用的功能代码)
rules\ (自定义验证规则)
is-confirm.rule.ts
is-not-exists.rule.ts
validate.ts (通用数据验证)
prisma\
prisma.module.ts (模块)
prisma.service.ts (处理与Prisma数据库交互的服务)
app.module.ts (模块)
main.ts (主入口)
transform.inteceptor.ts (响应拦截器)
——————————————————————————————————————
schema.prisma
定义数据库模型
generator client {provider = "prisma-client-js"
}datasource db {provider = "mysql"url = env("DATABASE_URL")
}model user {id Int @id @default(autoincrement()) @db.UnsignedIntname String @uniquepassword String
}model article {id Int @id @default(autoincrement()) @db.UnsignedInttitle Stringcontent String @db.Text
}
seed.ts
填充数据库数据
import { PrismaClient } from "@prisma/client"
import { hash } from "argon2"
import { Random } from "mockjs"const prisma = new PrismaClient() //注册Prisma
async function run() {await prisma.user.create({ //往user表里面插入数据data: {name: "admin",password: await hash("admin8888") //转成hash}})for (let i = 0; i < 50; i++) { //填充50组await prisma.article.create({ //往article表里面插入数据data: {title: Random.ctitle(10, 30), //随机题目content: Random.cparagraph(10, 20), //随机内容}})}}
run()
——————————————————————————————————————
app.module.ts
import { Module } from '@nestjs/common';
import { AuthModule } from './auth/auth.module'; //引入验证模块
import { PrismaModule } from './prisma/prisma.module'; //引入prisma模块@Module({imports: [ AuthModule , PrismaModule ], //插入
})
export class AppModule {}
——————————————————————————————————————
auth
dto
register.dto.ts
import { IsNotEmpty } from "class-validator"; //引入默认不为空验证
import { IsNotExistsRule } from "../../common/rules/is-not-exists.rule"; //引入自定义验证
import { IsConfiemRule } from "../../common/rules/is-confirm.rule"; //引入自定义验证export default class RegisterDto { @IsNotEmpty({ message:'用户名不能为空' }) //验证规则@IsNotExistsRule("user" , { message: "用户已经存在" }) //验证规则name:string; //类型@IsNotEmpty({ message:'密码不能为空' })@IsConfiemRule({ message: "两次密码不一致" })password:string@IsNotEmpty({message: "确认密码不能为空"})password_confirm: string
}
auth.controller.ts
import { Controller , Body , Post } from '@nestjs/common'
import { AuthService } from './auth.service';
import RegisterDto from './dto/register.dto'; //引入验证规则@Controller()
export class AuthController{constructor(private auth: AuthService) {}@Post('register') //post请求,路由为registerlogin(@Body() dto: RegisterDto) { //获取body数据 为dto : 验证规则return this.auth.register(dto) //执行auth的register函数}
}
auth.service.ts
import { Injectable } from '@nestjs/common'
import RegisterDto from './dto/register.dto';
import { PrismaService } from './../prisma/prisma.service'; //引入全局配置prisma
import { hash } from 'argon2';
import { JwtService } from '@nestjs/jwt';@Injectable()
export class AuthService {constructor(private prisma:PrismaService , private jwt: JwtService){}async register(dto: RegisterDto){ //验证通过后执行这里const user = await this.prisma.user.create({ //等候创建data:{name: dto.name,password: await hash(dto.password)}})return this.token(user); //执行token函数}private async token({ id , name }){return {token: await this.jwt.signAsync({ //执行配置好后的jwtname , sub: id })}}
}
auth.module.ts
import { Module } from '@nestjs/common'
import { AuthService } from './auth.service'
import { AuthController } from './auth.controller'
import { JwtModule } from '@nestjs/jwt'
import { ConfigModule, ConfigService } from '@nestjs/config'@Module({imports: [ //TODO 配置JWTJwtModule.registerAsync({imports: [ConfigModule],inject: [ConfigService],useFactory: (config: ConfigService) => {return {secret: config.get('TOKEN_SECRET'), //密钥在.env里配置signOptions: { expiresIn: '60d' } //持续时间}},})], //ENDcontrollers: [AuthController], //引入控制器providers: [AuthService] //引入函数
})export class AuthModule{}
common
rules
is-confirm.rule.ts
import { PrismaClient } from '@prisma/client'
import { registerDecorator , ValidationArguments , ValidationOptions } from 'class-validator'//表字段是否唯一
export function IsConfiemRule( //这里定义规则名称validationOptions?: ValidationOptions
) {return function (object: Record<string , any>, propertyName: string) {registerDecorator({name: 'IsConfiemRule', //同上target: object.constructor,propertyName: propertyName,constraints: [],options: validationOptions,validator: {async validate(value: string, args: ValidationArguments) {//TODOreturn Boolean(value == args.object[`${args.property}_confirm`]) //true为通过,false为不通过//END}}})}
}
is-not-exists.ule.ts
import { PrismaClient } from '@prisma/client'
import { registerDecorator , ValidationArguments , ValidationOptions } from 'class-validator'//表字段是否唯一
export function IsNotExistsRule(table: string,validationOptions?: ValidationOptions
) {return function (object: Record<string , any>, propertyName: string) {registerDecorator({name: 'IsNotExistsRule',target: object.constructor,propertyName: propertyName,constraints: [table],options: validationOptions,validator: {async validate(value: string, args: ValidationArguments) {//TODOconst prisma = new PrismaClientconst res = await prisma[table].findFirst({where: {[args.property]: value}})return !Boolean(res)//END}}})}
}
//同上
validate.ts
import { HttpException, HttpStatus, ValidationPipe } from "@nestjs/common";
import { ValidationError } from "class-validator";export default class Validate extends ValidationPipe {protected flattenValidationErrors(validationErrors: ValidationError[]): string[] {const messages = {}validationErrors.forEach(error => { //遍历出必要错误返回给前端messages[error.property] = Object.values(error.constraints)[0];})throw new HttpException({ //返回给前端的错误code: 422, messages}, HttpStatus.UNPROCESSABLE_ENTITY); }
}
prisma
prisma.module.ts
import { Global, Module } from '@nestjs/common'
import { PrismaService } from './prisma.service';@Global() // 全局模块
@Module({providers: [PrismaService],exports: [PrismaService]
})export class PrismaModule{}
prisma.service.ts
import { PrismaClient } from '@prisma/client'
import { Injectable } from '@nestjs/common'@Injectable()
export class PrismaService extends PrismaClient{constructor(){super({log:['query']})}
}
transform.inteceptor.ts
import { CallHandler , ExecutionContext , Injectable , NestInterceptor } from '@nestjs/common'
import { map } from 'rxjs/operators'@Injectable()
export class TransformInterceptor implements NestInterceptor { //修改一下数据格式intercept(context: ExecutionContext, next: CallHandler) {return next.handle().pipe(map((data) => {return {data}}))}
}
main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import Validate from './common/validate';
import { TransformInterceptor } from './transform.inteceptor';async function bootstrap() {const app = await NestFactory.create(AppModule);app.useGlobalPipes(new Validate()) //返回给前端的错误数据app.useGlobalInterceptors(new TransformInterceptor()) //返回给前端的正确数据(响应拦截器)await app.listen(3000); //监听的端口号
}
bootstrap();
这篇关于Nest.js项目小结1的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!