如何优雅的处理Restful
最近公司搭建的项目,前端反映后端返回格式不统一的问题,因此引发小编的思考,如何能够优雅的处理返回值格式呢?在度娘中仔细研读了一番,决定总结一下,于是乎此文便诞生了。
一、背景
首先,大家都会思考为什么要做统一格式处理呢?
现阶段的开发模式多以前后端分离形式存在,前后端开发人员需要通过大量 API 来进行数据交互,如果在交互过程中前后端人员经常遭遇如下问题:
-
前端人员不能快速理解接口字段含义及接口字段变化
-
后端人员想复用某些接口,但是不能快速从接口 URL 的定义中明确该接口的含义,需要进一步读代码确认
-
URL中的英文单词使用五花八门,搜索某个接口不知道具体的关键字
-
请求方法动词如 POST GET 随意使用
-
完成当前业务接口对接,前端人员经常会询问下一步业务流程的接口定义在哪里,对接形式是什么样的
以上只是前后端人员通过接口交互的一小部分问题,这些问题就好比"牙痛",不致命,但是在整个软件开发的生命周期内,天天"牙痛”是很要命的, 需要解决上述的问题,需要前后端人员都能认识与了解接口设计规范的重要性。因此,如何让前端小伙伴可以处理标准的 response JSON 数据结构都至关重要。
通过上面一个问题把大家带入正题,下面我们统一定义一下格式。
二、格式定义
2.1结果格式定义
每一次 RESTful 请求都应该包含以下几个信息:
名称 |
描述 |
success |
标识请求成功与否,false、true |
code |
状态码,标识错误类型 |
message |
提示信息 |
data |
返回数据 |
2.2结果枚举类定义
/** * @Author:qxy * @Date:2020/4/7 13:07 */ public enum ResultCodeEnum { /*** 通用部分 100 - 599***/ // 成功请求 SUCCESS(200, "successful"), // 重定向 REDIRECT(301, "redirect"), // 资源未找到 NOT_FOUND(404, "not found"), // 服务器错误 SERVER_ERROR(500,"server error"), BUSINESS_EXCEPTION(4000, "business exception"), ; private Integer code; private String message; //省略get/set方法
}
为了日常开发中规范状态码,这里着重参考一下Http定义的规范:
常见的HTTP状态码如: 200 - 请求成功; 301 - 资源(网页等)被永久转移到其它URL; 404 - 请求的资源(网页等)不存在; 500 - 内部服务器错误。 message:错误信息 在发生错误时,如何友好的进行提示? 1.根据code 给予对应的错误码定位; 2.把错误描述记录到message中,便于接口调用者更详细的了解错误。
状态码类型 |
code区间 |
类型 |
含义 |
1 |
100-199 |
信息 |
服务器接收到请求,需要请求者继续执行操作 |
2 |
200-299 |
成功 |
请求被成功接收并处理 |
3 |
300-399 |
重定向 |
需要进一步的操作以完成请求 |
4 |
400-499 |
客户端错误 |
请求包含语法错误或无法完成请求 |
5 |
500-599 |
服务端错误 |
服务器在处理的时候发生错误 |
2.3统一结果类
/** * @Author:qxy * @Date:2020/4/7 13:11 */ public class HttpResult<T> implements Serializable { private Boolean success; private Integer code; private String message; private T data; //省略get/set /** * 无参构造 */ public HttpResult() { this.success = true; this.code = ResultCodeEnum.SUCCESS.getCode(); this.message = ResultCodeEnum.SUCCESS.getMessage(); } /** * 有参构造:返回成功 * @param object */ public HttpResult(T object) { this.success = true; this.code = ResultCodeEnum.SUCCESS.getCode(); this.message = ResultCodeEnum.SUCCESS.getMessage(); this.data = object; } /** * 有参构造:返回失败 * @param resultCode */ public HttpResult(ResultCodeEnum resultCode) { this.success = false; this.code = resultCode.getCode(); this.message = resultCode.getMessage(); } }
2.4定义业务场景返回类
/** * @Author:qxy * @Date:2020/4/7 13:57 */ public class ResultResponse { /** * 通用返回成功(没有返回结果) * @param * @return */ public static HttpResult success(){ return new HttpResult(); } /** * 返回成功(有返回结果) * @param data * @return */ public static<T> HttpResult success(T data){ return new HttpResult<T>(data); } /** * 通用返回失败 * @param resultCode * @param <T> * @return */ public static<T> HttpResult<T> failure(ResultCodeEnum resultCode){ return new HttpResult<T>(resultCode); } /** * 捕获异常类型设置状态和提示信息 * @param code * @param message * @param <T> * @return */ public static<T> HttpResult<T> failure(Integer code, String message) { ResultCodeEnum resultCodeEnum = ResultCodeEnum.BUSINESS_EXCEPTION; resultCodeEnum.setCode(code); resultCodeEnum.setMessage(message); return failure(resultCodeEnum); } }
三、测试
/** * @Author:qxy * @Date:2020/4/7 9:45 */ @RestController public class StudentController { @Autowired private StudentService studentService; @GetMapping("/getStudentList") public HttpResult getStudentList(){ return ResultResponse.success(studentService.getStudentList()); } }
详细代码请移步github下载:https://github.com/stream-source/stream-source/tree/master/informal-essay/src/main/java/com/qxy/response
参考资料:风尘博客