nestjs HTTP 状态码从入门到精通 - 指南

一、HTTP 状态码基础

在 RESTful API 设计中,状态码用于明确表达请求处理结果:

  • 2xx:成功(200 OK, 201 Created)
  • 3xx:重定向(301, 302)
  • 4xx:客户端错误(400 Bad Request, 401 Unauthorized)
  • 5xx:服务端错误(500 Internal Server Error)

二、NestJS 设置状态码的 4 种方式

1. @HttpCode() 装饰器
import { Post, HttpCode
} from '@nestjs/common';
@Controller('cats')
export class CatsController
{
@Post()
@HttpCode(201) // 强制返回 201 Created
create() {
return { id: 1, name: 'Kitty'
};
}
}

特点

  • 仅修改成功响应(2xx)的状态码
  • 不影响异常状态码(如 4xx/5xx)
2. 手动设置响应对象
import { Post, Res
} from '@nestjs/common';
import { Response
} from 'express';
@Post('manual')
createManual(@Res() res: Response) {
res.status(202).json({ status: 'Accepted'
});
}

注意

  • 使用 @Res() 后需手动处理响应
  • 会覆盖 @HttpCode() 的设置
3. 异常过滤器(Exception Filters)
import { Catch, ExceptionFilter, ArgumentsHost
} from '@nestjs/common';
import { Response
} from 'express';
@Catch(ValidationError)
export class ValidationFilter
implements ExceptionFilter {
catch(exception: ValidationError, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse<Response>();
  response.status(400).json({ error: 'Invalid data'
  });
  }
  }

适用场景

  • 自定义错误响应状态码
  • 全局错误处理(如 401/500)
4. 库函数自动设置
  • @nestjs/common 内置异常类自动设置状态码:
    throw new NotFoundException('Resource not found');
    // 404
    throw new ForbiddenException('Access denied');
    // 403

三、@HttpCode() 装饰器深度解析

1. 优先级规则
@Post()
@HttpCode(202) // 最终状态码为 204
async create(@Res() res: Response) {
res.status(204);
// 手动设置优先级最高
}

优先级:手动设置 > 异常过滤器 > @HttpCode()

2. 默认行为
  • GET/PUT/PATCH/DELETE:默认 200 OK
  • POST:默认 201 Created
  • 异常抛出:由异常类型决定(如 404/500)
3. 动态状态码
@Post(':id')
@HttpCode((req) => req.params.id ? 200 : 201)
update(@Param('id') id: string) {
return id ? { updated: true
} : { created: true
};
}

四、常见问题解决方案

1. 为什么 @HttpCode() 不生效?
  • 检查是否同时使用了 @Res() 或抛出了异常
  • 确保没有其他装饰器覆盖状态码
2. 如何统一修改默认状态码?
// 全局拦截器修改默认 POST 状态码
@Injectable()
export class HttpCodeInterceptor
implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler) {
const res = context.switchToHttp().getResponse();
res.status(HttpStatus.CREATED);
return next.handle();
}
}
3. HEAD 请求的特殊处理
@Head()
@HttpCode(204) // HEAD 请求通常返回 204 No Content
checkStatus() {
return;
}

五、底层实现原理

  1. 框架集成
    • Express 适配器:通过 response.statusCode 设置
    • Fastify 适配器:通过 reply.code() 设置
  2. 生命周期
    请求进入
    路由匹配
    执行拦截器
    执行控制器方法
    是否抛出异常?
    异常过滤器处理
    应用最终状态码
    发送响应

六、最佳实践建议

  1. RESTful 规范
    • POST → 201 Created
    • DELETE → 204 No Content
    • 批量操作 → 207 Multi-Status
  2. 幂等性控制
    @Patch(':id')
    @HttpCode(200) // 明确幂等操作的状态码
    partialUpdate() {
    ...
    }
  3. 性能优化
    • 避免在高频接口使用动态状态码
    • 优先使用装饰器而非手动设置

通过合理运用这些技术,您可以精确控制 API 的状态码行为,同时保持代码的可维护性。建议结合 Swagger 等工具进行 API 文档化,确保状态码约定清晰可见。

posted on 2025-07-25 14:20  ljbguanli  阅读(14)  评论(0)    收藏  举报