当前位置: 首页 > news >正文

如何设计出优秀、健壮且易于维护的API——关于HTTP状态码与业务逻辑状态码的处理 - 浪矢

目录
  • 反例
  • 正确的处理方法
    • 第1步:在业务逻辑层定义并抛出“业务异常”
    • 第2步:在最外层创建“全局异常处理器”
  • 最佳实践

反例

刚开始学习后端开发时做了一个文件管理系统,其中有一个文件删除的API。
文件和目录删除操作 Delete 接口的设计的很粗糙 :HTTP状态码和业务逻辑状态码都返回给请求方了。
业务逻辑状态码:删除操作执行成功逻辑状态码code=200,删除失败逻辑状态码code=500;文件不存在code=FS4004;无管理权限code=FS4003.
http状态码:只要请求成功就返回200。
这就导致了一个问题,因为我的处理逻辑比较复杂,请求方每次读到http状态码为200就认为删除成功了。
但是我们测试删除操作时,并不存在的文件时也显示http code=200,但我们更想给请求方更多的信息。

正确的处理方法

第1步:在业务逻辑层定义并抛出“业务异常”

当删除操作失败时,不要直接返回一个包含错误码的普通对象,而是抛出一个能描述业务错误的自定义异常。

点击查看代码
// 你的文件删除服务 (FileService.java)
public void deleteFile(String fileId, String userId) {File file = fileRepository.findById(fileId);// 业务场景1:文件不存在if (file == null) {// 抛出业务异常,而不是返回一个错误对象throw new BusinessException("FS4004", "文件不存在");}// 业务场景2:权限不足if (!file.getOwnerId().equals(userId)) {throw new BusinessException("FS4003", "无权删除该文件");}// ... 执行删除操作boolean deleted = doDelete(file);// 业务场景3:未知的内部错误导致删除失败if (!deleted) {throw new BusinessException("SYS5000", "删除操作失败,请联系管理员");}
}

第2步:在最外层创建“全局异常处理器”

在你的 trigger 层(通常是 Spring MVC 中),创建一个全局异常处理器。它的职责就是捕获从业务层抛出的 BusinessException,然后把它“翻译”成标准的 HTTP 响应。

点击查看代码
@RestControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler(BusinessException.class)public ResponseEntity<ApiResponse> handleBusinessException(BusinessException ex) {ApiResponse responseBody = new ApiResponse(ex.getCode(), ex.getMessage(), null);// 根据业务异常的类型,决定返回哪个HTTP状态码switch (ex.getCode()) {case "FS4004": // 文件不存在return new ResponseEntity<>(responseBody, HttpStatus.NOT_FOUND); // HTTP 404case "FS4003": // 无权限return new ResponseEntity<>(responseBody, HttpStatus.FORBIDDEN); // HTTP 403default: // 其他业务失败,如删除失败return new ResponseEntity<>(responseBody, HttpStatus.INTERNAL_SERVER_ERROR); // HTTP 500}}@ExceptionHandler(Exception.class)public ResponseEntity<ApiResponse> handleGenericException(Exception ex) {// 处理所有未被捕获的未知异常ApiResponse responseBody = new ApiResponse("SYS9999", "系统内部未知错误", null);return new ResponseEntity<>(responseBody, HttpStatus.INTERNAL_SERVER_ERROR); // HTTP 500}}
#### 第3步:Controller 保持简洁 做了以上两步后,Controller 会变得非常干净,它只需要调用业务逻辑,完全不用关心成功失败的判断和响应封装。
点击查看代码
@RestController
public class FileController {@Autowiredprivate FileService fileService;@DeleteMapping("/files/{id}")public ResponseEntity<ApiResponse> deleteFile(@PathVariable String id) {// 只管调用,成功了就往下走,失败了异常处理器会接管fileService.deleteFile(id, getCurrentUserId());// 如果代码能执行到这里,说明没有任何异常,删除成功ApiResponse responseBody = new ApiResponse("200", "删除成功", null);return new ResponseEntity<>(responseBody, HttpStatus.OK); // HTTP 200}
}

这不仅能让自己的代码更易于维护,也能让所有调用你接口的客户端(前端、其他后端服务等)更容易地进行合作开发。

最佳实践

一个优秀的 API 设计,应该让这两者协同工作,而不是混淆它们。
核心流程:

业务层:只关心业务逻辑,当业务失败时,抛出携带业务状态码的自定义异常(如 AppException )。

表现层(全局异常处理器):作为“翻译官”,捕获业务异常,然后将业务状态码映射到一个最贴切的 HTTP 状态码,并构建包含业务状态码的 JSON 响应体。

http://www.hskmm.com/?act=detail&tid=23013

相关文章:

  • 做题记录(Part 1. 基础算法)
  • Android项目实现自动获取手机号一键登录功能
  • 实用指南:零基础学AI大模型之Prompt提示词工程
  • 打造优雅的用户体验:自定义jQuery程序提示插件开发全解析
  • 免费股票API接口全面指南 - 详解
  • 贝尔数
  • 10.2
  • 十月牛气冲天计数题没做
  • ubuntu安装pbc库
  • 《电路基础》第六章学习笔记
  • Manim实现渐变填充特效
  • datadome 隐私模式 ck设置
  • 利用IOT-Tree消息流【标签读写】功能详细说明
  • 2025.10.2 2024CCPC重庆
  • Day09
  • 命令行实用技巧
  • CPU温度查看(Core Temp)
  • 实用指南:Python虚拟环境管理工具virtualenv详解
  • C#简单的连接本地SQL Server
  • 昆明理工大学通信工程26考研招生人数
  • 深入解析:python学智能算法(三十九)|使用PyTorch模块的normal()函数绘制正态分布函数图
  • 2025污水处理设备厂家 TOP 企业品牌推荐排行榜,一体化,生活,工业,养殖,医疗,农村,学校,餐厨,隧洞,高速污水处理设备公司推荐!
  • 2025上海律师事务所权威推荐榜:多领域专业服务口碑之选
  • 软件工程课程第一次团队作业
  • 完整教程:MeterSphere接口测试响应提取:JSONPath与正则表达式全指南
  • 2025无锡高配网咖实力厂家推荐:电竞设备与沉浸体验优选指南
  • 2025无锡网咖权威推荐榜:停车便利体验佳,畅享上网好时光
  • 2025全屋定制厂家权威推荐榜:品质工艺与空间美学典范
  • 2020 ICPC 银川 ABEGJK
  • 1.奖励函数的简要分析