Skip to content

开发规范

接口与路由

  • API 前缀:/api/v1
  • Swagger:/api-docs

项目结构

youlai-nest/
├── src/
│   ├── main.ts              # 应用入口
│   ├── app.module.ts        # 根模块
│   ├── auth/                # 认证与会话
│   ├── system/              # 系统管理
│   ├── platform/            # 平台能力
│   ├── common/              # 通用能力
│   ├── shared/              # 共享基础设施
│   └── config/              # 配置模块
├── sql/                     # 数据库脚本
├── .env                     # 基础配置
├── .env.dev                 # 开发环境配置
├── .env.prod                # 生产环境配置
└── package.json             # 项目配置

目录约定

目录说明
src/auth认证与会话(登录/Token/验证码)
src/system系统管理(用户/角色/菜单/部门/字典)
src/platform平台能力(文件/代码生成/WebSocket)
src/common通用能力(异常/拦截器/守卫/上下文)
src/shared共享基础设施(Redis/Logger)
src/config配置模块(TypeORM/Redis/OSS/JWT)

开发规范

架构分层

  • Controller:接收请求,调用 Service,返回响应
  • Service:业务逻辑处理
  • Repository:数据库操作(TypeORM)

重要:Controller 禁止直接注入 Repository,必须通过 Service 操作数据库。

路由顺序

静态路由在前,动态路由在后,避免 :id 抢占:

typescript
@Controller('users')
export class UserController {
  @Put('read-all')  // 静态路由在前
  readAll() {}

  @Put(':id')       // 动态路由在后
  update() {}
}

新模块创建

建议沿用项目结构:

  • 系统模块:src/system/<module>
  • 平台模块:src/platform/<module>

命名规范

文件命名

  • 小驼峰:user.controller.ts, user.service.ts
  • 类名大驼峰:UserController, UserService

接口命名

typescript
// RESTful 风格
@Controller('users')
export class UserController {
  @Get()          // GET /api/v1/users
  findAll() {}

  @Get(':id')     // GET /api/v1/users/:id
  findOne() {}

  @Post()         // POST /api/v1/users
  create() {}

  @Put(':id')     // PUT /api/v1/users/:id
  update() {}

  @Delete(':id')  // DELETE /api/v1/users/:id
  remove() {}
}

参数校验

使用 DTO + class-validator

typescript
import { IsString, IsInt, Min, Max, IsOptional } from 'class-validator';

export class CreateUserDto {
  @IsString()
  @MaxLength(50)
  username: string;

  @IsString()
  @MinLength(6)
  @MaxLength(20)
  password: string;

  @IsInt()
  @IsOptional()
  @Min(1)
  deptId?: number;
}

配合全局 ValidationPipe

typescript
// main.ts
app.useGlobalPipes(new ValidationPipe({
  transform: true,
  whitelist: true,
}));

统一响应

所有接口返回统一格式:

typescript
interface Result<T> {
  code: string;
  msg: string;
  data: T;
}

成功响应

typescript
return { code: '00000', msg: '操作成功', data: user };

错误响应

typescript
throw new BusinessException('A0001', '认证失败');

错误处理

自定义异常

typescript
export class BusinessException extends HttpException {
  constructor(code: string, msg: string) {
    super({ code, msg, data: null }, HttpStatus.OK);
  }
}

全局异常过滤器

typescript
@Catch()
export class GlobalExceptionFilter implements ExceptionFilter {
  catch(exception: unknown, host: ArgumentsHost) {
    // 统一异常处理
  }
}

接口幂等

  • 优先使用数据库唯一约束兜底
  • 对高风险写操作使用 Redis 分布式锁
typescript
// 分布式锁示例
const lockKey = `lock:order:${orderId}`;
const locked = await this.redisService.lock(lockKey, 30);
if (!locked) {
  throw new BusinessException('A0004', '操作进行中,请勿重复提交');
}
try {
  // 业务处理
} finally {
  await this.redisService.unlock(lockKey);
}

代码风格

  • ESLint + Prettier
  • 使用项目脚本:pnpm lint / pnpm lint:fix

相关文件

文件说明
src/common/exception/异常处理
src/common/interceptor/响应拦截器
src/common/guard/认证守卫
src/common/decorator/自定义装饰器
eslint.config.mjsESLint 配置

基于 MIT 许可发布