编码习惯之接口定义

工作中,少不了要定义各种接口,系统集成要定义接口,前后台掉调用也要定义接口。接口定义一定程度上能反应程序员的编程功底。列举一下工作中我发现大家容易出现的问题:

1. 返回格式不统一

同一个接口,有时候返回数组,有时候返回单个;成功的时候返回对象,失败的时候返回错误信息字符串。工作中有个系统集成就是这样定义的接口,真是辣眼睛。这个对应代码上,返回的类型是map,json,object,都是不应该的。实际工作中,我们会定义一个统一的格式,就是ResultBean,分页的有另外一个PageResultBean

错误范例:

//返回map可读性不好,尽量不要

 @PostMapping("/delete")
 public Map<String, Object> delete(long id, String lang) {

 }
 // 成功返回boolean,失败返回string,大忌
 @PostMapping("/delete")
 public Object delete(long id, String lang) {
   try {
     boolean result = configService.delete(id, local);
     return result;
   } catch (Exception e) {
     log.error(e);
     return e.toString();
   }
 }

 

2. 没有考虑失败情况

一开始只考虑成功场景,等后面测试发现有错误情况,怎么办,改接口呗,前后台都改,劳民伤财无用功。

错误范例:

 //不返回任何数据,没有考虑失败场景,容易返工
 @PostMapping("/update")
 public void update(long id, xxx) {

 }

 

3. 出现和业务无关的输入参数

如lang语言,当前用户信息 都不应该出现参数里面,应该从当前会话里面获取。后面讲ThreadLocal会说到怎么样去掉。除了代码可读性不好问题外,尤其是参数出现当前用户信息的,这是个严重问题。

错误范例:

 // (当前用户删除数据)参数出现lang和userid,尤其是userid,大忌
 @PostMapping("/delete")
 public Map<String, Object> delete(long id, String lang, String userId) {

 }

 

4. 出现复杂的输入参数

一般情况下,不允许出现例如json字符串这样的参数,这种参数可读性极差。应该定义对应的bean。

错误范例:

 // 参数出现json格式,可读性不好,代码也难看
 @PostMapping("/update")
 public Map<String, Object> update(long id, String jsonStr) {

 }

 

5. 没有返回应该返回的数据

例如,新增接口一般情况下应该返回新对象的id标识,这需要编程经验。新手定义的时候因为前台没有用就不返回数据或者只返回true,这都是不恰当的。别人要不要是别人的事情,你该返回的还是应该返回。

错误范例:

 // 约定俗成,新建应该返回新对象的信息,只返回boolean容易导致返工
 @PostMapping("/add")
 public boolean add(xxx) {
   return configService.add();

 }

 

 

很多人看了我的这篇文章 程序员你为什么这么累?,都觉得里面的技术也很简单,没有什么特别的地方,但是,实现这个代码框架之前,就是要你的接口的统一的格式ResultBean,aop才好做。有些人误解了,我那篇文章说的都不是技术,重点说的是编码习惯工作方式,如果你重点还是放在什么技术上,那我也帮不了你了。同样,如果我后面的关于习惯和规范的帖子,你重点还是放在技术上的话,那是丢了西瓜捡芝麻,有很多贴还是没有任何技术点呢。

附上ResultBean,没有任何技术含量:

@Data
public class ResultBean<T> implements Serializable {

 private static final long serialVersionUID = 1L;

 public static final int SUCCESS = 0;
 public static final int FAIL = 1;
 public static final int NO_PERMISSION = 2;
 private String msg = "success";
 private int code = SUCCESS;
 private T data;

 public ResultBean() {
   super();
 }
 public ResultBean(T data) {
   super();
   this.data = data;
 }
 public ResultBean(Throwable e) {
   super();
   this.msg = e.toString();
   this.code = FAIL ;
 }
}

统一的接口规范,能帮忙规避很多无用的返工修改和可能出现的问题。能使代码可读性更加好,利于进行aop和自动化测试这些额外工作。大家一定要重视。

 

以下摘自极客时间:

服务端把错误码反馈给客户端有两个目的,一是客户端可以展示错误码方便排查问题,二是客户端可以根据不同的错误码来做交互区分。

对于第一点方便客户端排查问题,服务端应该进行适当的收敛和规整错误码,而不是把服务内可能遇到的、来自各个系统各个层次的错误码,一股脑地扔给客户端提示给用户。

我的建议是,开发一个错误码服务来专门治理错误码,实现错误码的转码、分类和收敛逻辑,甚至可以开发后台,让产品来录入需要的错误码提示消息。

此外,我还建议错误码由一定的规则构成,比如错误码第一位可以是错误类型(比如 A 表示错误来源于用户;B 表示错误来源于当前系统,往往是业务逻辑出错,或程序健壮性差等问题;C 表示错误来源于第三方服务),第二、第三位可以是错误来自的系统编号(比如 01 来自用户服务,02 来自商户服务等等),后面三位是自增错误码 ID。

对于第二点对不同错误码的交互区分,我觉得更好的做法是服务端驱动模式,让服务端告知客户端如何处理,说白了就是客户端只需要照做即可,不需要感知错误码的含义(即便客户端显示错误码,也只是用于排错)。

比如,服务端的返回可以包含 actionType 和 actionInfo 两个字段,前者代表客户端应该做的交互动作,后者代表客户端完成这个交互动作需要的信息。其中,actionType 可以是 toast(无需确认的消息提示)、alert(需要确认的弹框提示)、redirectView(转到另一个视图)、redirectWebView(打开 Web 视图)等;actionInfo 就是 toast 的信息、alert 的信息、redirect 的 URL 等。

由服务端来明确客户端在请求 API 后的交互行为,主要的好处是灵活和统一两个方面。灵活在于两个方面:

第一,在紧急的时候还可以通过 redirect 方式进行救急。比如,遇到特殊情况需要紧急进行逻辑修改的情况时,我们可以直接在不发版的情况下切换到 H5实现。

第二是,我们可以提供后台,让产品或运营来配置交互的方式和信息(而不是改交互,改提示还需要客户端发版)。统一:有的时候会遇到不同的客户端(比如 iOS、Android、前端),对于交互的实现不统一的情况,如果 API 结果可以规定这部分内容,那就可以彻底避免这个问题。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

刘彦青-Yannis

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值