当前位置: 首页 > 科技观察

如何设计API接口实现统一格式返回?

时间:2023-03-17 14:12:42 科技观察

前言在移动互联网,分布式和微服务盛行的今天,现在大部分项目都使用微服务框架,前后端分离。堪称大前端,技术栈和生态系统非常成熟;以前后端人员看不起前端人员,现在后端人员不得不重新认识前端,前端已经很系统了)。通用系统的通用整体架构图如下:需要说明的是,有小伙伴会回复说这个架构太简单太low,没有网关,没有缓存,没有消息中间件。因为老谷这篇文章主要是介绍API接口,所以重点介绍一下,其他模块小伙伴可以自行补充。界面交互前端与后端交互。前端根据约定请求URL路径,并传入相关参数。后端服务器接收请求,进行业务处理,返回数据给前端。对于URL路径的restful风格,以及传入参数的公共请求头的要求(如:app_version、api_version、device等),老谷这里就不介绍了。小伙伴们可以自学,比较简单。后端服务器如何向前端返回数据?返回格式后端返回给前端。我们一般使用JSONbody方法,定义如下:{#返回状态码code:integer,#返回信息描述message:string,#返回值data:object}CODEstatuscodecode返回状态码,一般的朋友在开发过程中添加他们需要的任何东西。如果接口要返回用户权限异常,我们加状态码101,下次需要加数据参数异常,加状态码102,虽然这样可以满足正常业务,但是状态码代码太乱了。我们应该参考HTTP请求返回的状态码:以下是常见的HTTP状态码:200-请求成功301-资源(网页等)永久转移到另一个URL404-请求的资源(网页等)不存在500-内部服务器错误我们可以参考这个设计,它的好处是可以将错误类型划分到一定的范围内。如果范围不够,可以设计成4位。#1000~1999区间表示参数错误#2000~2999区间表示用户错误#3000~3999区间表示接口异常这样前端开发人员在得到返回值后根据状态码就可以知道是哪里出了问题,然后根据消息相关信息描述,可以快速定位。关注微信公众号Java后台获取更多更新。Message字段理解起来比较简单,就是发生错误时如何进行友好的提示。总体设计是和代码状态码一起设计的。如果定义在枚举中,状态码和信息会一一对应,更容易维护。Data返回数据体,JSON格式,根据不同的业务返回不同的JSON体。我们要设计一个返回体类Result控制层Controller。我们会在controller层处理业务请求,返回给前端。以订单订单为例,我们可以看到,在获取到订单对象后,我们使用Result构造方法进行封装赋值。然后返回。小伙伴们有没有发现构造方法的打包不是很麻烦,我们可以优化一下。关注微信公众号Java后台获取更多更新。美化我们可以在Result类中添加静态方法,一目了然。那么我们来修改一下Controller的代码,让它更加简洁美观。优雅优化上面我们看到Result类增加了静态方法,使得业务处理代码更加简洁。但是大家有没有发现有几个问题:1、每个方法返回的都是一个Result包对象,没有业务意义。2、在业务代码中,我们在成功时调用Result.success,在出现异常时调用Result。失败。是不是太多了?3、上面的代码,判断id是不是,其实我们可以使用hibernatevalidate来做校验,不需要在方法体中判断。我们最好的办法是直接返回真正的业务对象。最好不要改变以前的经营方式。下图和我们平时的代码是一样的。非常直观,直接返回订单对象。这不是很完美吗?实施计划为何?你们对如何实施实施计划有什么想法吗?在这个过程中,我们需要做一些事情。1、定义一个注解@ResponseResult,表示该接口返回的值需要进行封装。2.拦截请求,判断请求是否需要@ResponseResult注解3.核心步骤是实现接口ResponseBodyAdvice和@ControllerAdvice,判断返回值是否需要封装,必要时重写返回控制器接口的值。注解类用于标记方法的返回值,是否需要包装拦截器拦截请求,本次请求返回的值是否需要包装。其实在运行的时候,解析这段代码的@ResponseResult注解的核心思想就是获取这个请求以及是否需要返回一个设置了属性标签的值包装器。重写返回体上面的代码是判断是否需要返回值包装,需要的话直接包装。这里我们只处理正常的成功包装,如果方法体报异常怎么办?处理异常也比较简单,判断body是否为异常类即可。如何做全局异常处理,限于篇幅,老谷这里就不介绍了,只要思路清晰,大家可以自己修改。重写Controller,在controller类或方法体上加上@ResponseResult注解,就ok了,简单。到这里返回的设计思路就完成了,是不是简洁大方?