控制器
什么是控制器?
想象一下,你在一家餐厅点餐:
- 你(客户端)告诉服务员(控制器)你想要什么菜
- 服务员把你的需求传达给厨房(服务层)
- 厨房做好菜后,服务员把菜端给你
在 NestJS 中,控制器(Controller) 就是那个"服务员",它负责:
- 接收来自客户端的请求
- 处理请求并调用相应的业务逻辑
- 返回响应给客户端
基本语法
1. 创建一个简单的控制器
typescript
import { Controller, Get } from '@nestjs/common';
@Controller('cats') // 这是控制器装饰器
export class CatsController {
@Get() // 这是路由装饰器
findAll(): string {
return '这个接口返回所有猫咪信息';
}
}解释:
@Controller('cats')表示这个控制器处理所有以/cats开头的请求@Get()表示这个方法处理 GET 请求- 当访问
GET /cats时,会调用findAll()方法
2. 不同的HTTP方法
typescript
import { Controller, Get, Post, Put, Delete } from '@nestjs/common';
@Controller('users')
export class UsersController {
@Get()
getAllUsers() {
return '获取所有用户';
}
@Post()
createUser() {
return '创建新用户';
}
@Put()
updateUser() {
return '更新用户信息';
}
@Delete()
deleteUser() {
return '删除用户';
}
}访问方式:
GET /users→getAllUsers()POST /users→createUser()PUT /users→updateUser()DELETE /users→deleteUser()
路由参数
1. 路径参数
typescript
import { Controller, Get, Param } from '@nestjs/common';
@Controller('users')
export class UsersController {
@Get(':id')
findOne(@Param('id') id: string) {
return `查找ID为 ${id} 的用户`;
}
@Get(':id/posts/:postId')
findUserPost(
@Param('id') userId: string,
@Param('postId') postId: string
) {
return `用户 ${userId} 的文章 ${postId}`;
}
}示例访问:
GET /users/123→ 返回 "查找ID为 123 的用户"GET /users/123/posts/456→ 返回 "用户 123 的文章 456"
2. 查询参数
typescript
import { Controller, Get, Query } from '@nestjs/common';
@Controller('products')
export class ProductsController {
@Get()
findAll(@Query() query: any) {
return `搜索参数: ${JSON.stringify(query)}`;
}
@Get('search')
search(
@Query('keyword') keyword: string,
@Query('page') page: number = 1
) {
return `搜索关键词: ${keyword}, 页码: ${page}`;
}
}示例访问:
GET /products?category=electronics&price=100GET /products/search?keyword=laptop&page=2
请求体处理
1. 接收POST数据
typescript
import { Controller, Post, Body } from '@nestjs/common';
// 定义数据传输对象(DTO)
export class CreateUserDto {
name: string;
email: string;
age: number;
}
@Controller('users')
export class UsersController {
@Post()
create(@Body() createUserDto: CreateUserDto) {
return `创建用户: ${createUserDto.name}, 邮箱: ${createUserDto.email}`;
}
@Post('login')
login(@Body() loginData: { username: string; password: string }) {
return `用户 ${loginData.username} 尝试登录`;
}
}2. 组合使用参数和请求体
typescript
import { Controller, Put, Param, Body } from '@nestjs/common';
@Controller('users')
export class UsersController {
@Put(':id')
update(
@Param('id') id: string,
@Body() updateData: { name?: string; email?: string }
) {
return `更新用户 ${id}: ${JSON.stringify(updateData)}`;
}
}更多装饰器
1. 请求头处理
typescript
import { Controller, Get, Headers } from '@nestjs/common';
@Controller('api')
export class ApiController {
@Get('info')
getInfo(@Headers('authorization') auth: string) {
return `认证信息: ${auth}`;
}
}2. 响应对象
typescript
import { Controller, Get, Res } from '@nestjs/common';
import { Response } from 'express';
@Controller('files')
export class FilesController {
@Get('download')
downloadFile(@Res() res: Response) {
res.download('./files/example.txt');
}
}实际应用示例
完整的用户管理控制器
typescript
import { Controller, Get, Post, Put, Delete, Param, Body, Query } from '@nestjs/common';
// 数据传输对象
export class CreateUserDto {
name: string;
email: string;
age: number;
}
export class UpdateUserDto {
name?: string;
email?: string;
age?: number;
}
@Controller('users')
export class UsersController {
// 获取所有用户(支持分页)
@Get()
findAll(@Query('page') page: number = 1, @Query('limit') limit: number = 10) {
return `获取用户列表 - 第${page}页,每页${limit}条`;
}
// 根据ID获取用户
@Get(':id')
findOne(@Param('id') id: string) {
return `获取用户 ${id} 的详细信息`;
}
// 创建新用户
@Post()
create(@Body() createUserDto: CreateUserDto) {
return `创建用户: ${createUserDto.name}`;
}
// 更新用户信息
@Put(':id')
update(@Param('id') id: string, @Body() updateUserDto: UpdateUserDto) {
return `更新用户 ${id} 的信息`;
}
// 删除用户
@Delete(':id')
remove(@Param('id') id: string) {
return `删除用户 ${id}`;
}
// 搜索用户
@Get('search/:keyword')
search(@Param('keyword') keyword: string) {
return `搜索包含 "${keyword}" 的用户`;
}
}控制器的注册
创建控制器后,需要在模块中注册:
typescript
import { Module } from '@nestjs/common';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';
@Module({
controllers: [UsersController], // 在这里注册控制器
providers: [UsersService],
})
export class UsersModule {}命令行快速创建
NestJS 提供了命令行工具来快速创建控制器:
bash
# 创建一个名为 cats 的控制器
nest generate controller cats
# 简写形式
nest g controller cats
# 创建完整的 CRUD 控制器
nest g resource cats常见错误和解决方案
1. 路由冲突
typescript
// ❌ 错误:会产生冲突
@Controller('users')
export class UsersController {
@Get('active')
getActiveUsers() { ... }
@Get(':id') // 这个会拦截所有GET请求,包括 /users/active
getUser(@Param('id') id: string) { ... }
}
// ✅ 正确:具体路由放在参数路由前面
@Controller('users')
export class UsersController {
@Get(':id')
getUser(@Param('id') id: string) { ... }
@Get('active') // 这样就不会冲突了
getActiveUsers() { ... }
}2. 参数类型转换
typescript
@Controller('users')
export class UsersController {
@Get(':id')
findOne(@Param('id') id: string) {
// id 始终是字符串,如果需要数字要手动转换
const userId = parseInt(id, 10);
return `用户ID: ${userId}`;
}
}总结
控制器是 NestJS 应用的入口点,它们:
- 定义路由 - 决定哪个 URL 对应哪个方法
- 处理请求 - 接收和解析客户端发送的数据
- 返回响应 - 把处理结果返回给客户端
记住这个模式:
- 用
@Controller()装饰器定义控制器 - 用
@Get(),@Post()等装饰器定义路由 - 用
@Param(),@Body(),@Query()等装饰器获取请求数据
从简单的例子开始,逐步增加复杂度,你很快就能掌握 NestJS 控制器的使用!
