新增 API 接口

创建 Controller

api/src/controllers/ 下创建文件:

// api/src/controllers/todo.controller.ts
import { Controller, Get, Post, Body, Req, Res, UseGuards } from "@nestjs/common"
import { Response } from "express"
import { JwtAuthGuard } from "@readystart/api-core/shared/guards/jwt.auth.guard"
import { CustomRequest } from "@readystart/api-core/shared/interfaces/request.interface"
import { ResponseHandler } from "@readystart/api-core/shared/utils/response.handler"
import { PgsqlService } from "@readystart/api-core/shared/services/pgsql.service"

@UseGuards(JwtAuthGuard)
@Controller({ version: "1", path: "todos" })
export class TodoController {
  constructor(private readonly pgsqlService: PgsqlService) {}

  @Post("create")
  async create(
    @Req() req: CustomRequest,
    @Body() body: { title: string },
    @Res() res: Response
  ) {
    const tenant_id = req.tenant?.id
    const result = await this.pgsqlService.query(
      `INSERT INTO todos (tenant_id, title) VALUES ($1, $2) RETURNING *`,
      [tenant_id, body.title]
    )
    res.json({ statusCode: 200, data: result.rows[0], message: "success" })
  }

  @Post("list")
  async list(@Req() req: CustomRequest, @Res() res: Response) {
    const tenant_id = req.tenant?.id
    const result = await this.pgsqlService.query(
      `SELECT * FROM todos WHERE tenant_id = $1 ORDER BY created_at DESC`,
      [tenant_id]
    )
    res.json({ statusCode: 200, data: result.rows, message: "success" })
  }
}

注册到 Module

// api/src/app.module.ts
import { TodoController } from "./controllers/todo.controller"

@Module({
  controllers: [
    // ... 其他 controller
    TodoController,
  ],
})
export class AppModule {}

DTO 验证

使用 class-validator 验证请求参数:

// api/src/controllers/todo.dto.ts
import { IsNotEmpty, Length } from "class-validator"

export class CreateTodoDto {
  @IsNotEmpty({ message: "title is required" })
  @Length(1, 255)
  title: string
}

在 Controller 中使用:

@Post("create")
async create(@Body() body: CreateTodoDto, ...) {
  // body.title 已经过验证
}

响应格式

所有接口统一返回格式:

{
  "statusCode": 200,
  "data": {},
  "message": "success"
}

使用 ResponseHandler 处理异步响应:

await ResponseHandler.handleMicroserviceResponse(
  res,
  this.myService.doSomething()
)

路由版本

所有接口默认带版本前缀 /v1/

POST /v1/todos/create
POST /v1/todos/list