如何在调用REST API的方法中返回MyObject或MyError两种类型对象
方案解答
你当前自定义包含MyObject和MyError两个字段的HandleResponse方案是可行的,属于业内常用的基础实现思路,没有逻辑错误,也可以根据技术栈和业务场景选择更规范、可维护性更高的处理方案:
1 现有思路的优化方案
如果要沿用你当前的实现,建议给HandleResponse封装内置的判断和取值方法,避免调用方每次手动判空出现逻辑漏洞:
- 新增
isSuccess()方法内部判断错误字段是否为空,对外暴露统一的判断入口 - 取值方法(
getData()/getError())内部先校验当前状态,状态不匹配直接抛出明确的异常,避免调用方在请求失败的场景下误取成功数据 - 新增静态构造方法,避免调用方构造出非法的响应对象(比如两个字段都有值/都为空)
- Java参考实现:
public class ApiResponse<T> { // 泛型兼容不同类型的成功返回对象,不用每个返回类都单独定义响应类 private T data; private MyError error; public boolean isSuccess() { return error == null; } public T getData() { if (!isSuccess()) { throw new IllegalStateException("请求失败,无法获取成功数据"); } return data; } public MyError getError() { if (isSuccess()) { throw new IllegalStateException("请求成功,无法获取错误信息"); } return error; } public static <T> ApiResponse<T> success(T data) { ApiResponse<T> response = new ApiResponse<>(); response.data = data; return response; } public static <T> ApiResponse<T> fail(MyError error) { ApiResponse<T> response = new ApiResponse<>(); response.error = error; return response; } }
- 调用方使用方式:
ApiResponse<MyObject> response = callRestApi(); if (response.isSuccess()) { MyObject data = response.getData(); // 处理成功逻辑 } else { MyError error = response.getError(); // 处理错误逻辑 }
2 类型安全的规范实现(推荐)
如果你的技术栈支持密封类(Java 17+、Kotlin、Scala、C#等),可以用密封类+代数数据类型的方案,从语法层面避免非法响应对象的存在,不需要处理空值,编译器还能自动检查分支覆盖情况:
- Kotlin参考实现:
// 密封接口限定ApiResult只有两种合法子类 sealed interface ApiResult<out T> { data class Success<out T>(val data: T): ApiResult<T> data class Fail(val error: MyError): ApiResult<Nothing> }
- 调用方用模式匹配处理分支,不需要手动判空:
val result: ApiResult<MyObject> = callRestApi() when(result) { is ApiResult.Success -> handleSuccess(result.data) is ApiResult.Fail -> handleError(result.error) }
这个方案是目前业内最推荐的实现,完全避免了空值判断、非法对象构造的问题,代码可维护性更高。
3 异常处理方案
如果错误属于非预期的异常场景,不是业务常规返回,可以直接在API调用方法内部把MyError包装成自定义业务异常抛出,方法正常情况下只返回MyObject:
public MyObject callRestApi() throws BusinessException { // 调用API逻辑 if (response instanceof MyError) { throw new BusinessException((MyError) response); } return (MyObject) response; }
调用方用try-catch捕获异常处理错误即可,这个方案适合错误占比极低的场景,不适合错误是业务常规返回的场景,异常的性能开销也相对更高。
内容的提问来源于stack exchange,提问作者Fesilox
相关产品推荐
相关产品推荐

