控制器
什么是控制器?
想象一下,你在一家餐厅点餐:
- 你(客户端)告诉服务员(控制器)你想要什么菜
- 服务员把你的需求传达给厨房(服务层)
- 厨房做好菜后,服务员把菜端给你
在 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=100
GET /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 控制器的使用!