设计一个接口至少要考虑这14点!

  1. 入参合法性校验
  2. 接口的版本控制
  3. 接口考虑幂等性
  4. 接口考虑防止重复请求
  5. 提高接口的响应时间
  6. 接口限流控制
  7. 黑白IP白名单
  8. 敏感数据脱敏
  9. 请求接口的先决条件-token
  10. 记录接口请求日志
  11. 调用第三方接口要考虑异常、超时、重试
  12. 统一响应数据格式
  13. 接口单一职责
  14. 接口文档的可读性

在我们日常开发中设计一个接口的步骤大致如下:

Controller层定义接口url、请求方式、入参、统一格式的出参。然后在Service层去定义接口和实现类,这样一个接口就算完成了。

当然我们还需要考虑很多东西,比如接口的规范性安全性可扩展性稳定性等等。

这篇文就来整理下 设计一个良好的接口需要考虑哪些点呢?

1、入参合法性校验

入参的合法性校验是一个良好的接口必备的前提条件,通过入参的校验我们可以过滤掉许多无效的请求,提高系统的稳定性。

我们可以将入参合法性校验分为: 常规性校验业务校验;

所谓的常规性校验包括:token校验、必填校验、长度校验、类型校验等等;

业务校验也就是特定业务场景下的校验:比如用户商品下单接口,那么下单金额一定要大于0;

有关参数校验之前写过一篇文章:Spring Boot 实现各种参数校验

2、接口的版本控制

我们在开发小程序或者app的时候,都需要对版本进行升级,而提前设计好版本,可以避免因为升级导致旧的服务无法正常工作,我们要保证在升级的时候,新旧版本的服务都能正常运转。

多版本控制现在比较常见的方式有:url标识版本, header标识版本, params标识版本3种方式。

这里举url为例。接口定义:

http://localhost:8888/test/v{d}/hello,其中d表示版本号,如v1.0,v2.0

后台接口:

 @RequestMapping("test/v{d}/hello")
    public String hello(@PathVariable("id") Integer id){
        //根据不同版本,执行不同逻辑
        return "成功";
    }

基于url标识版本不友好的点在于,对于前端工程师来说会比较麻烦,必须在每个请求的URL上标记一个版本号来使用对应的版本的API。

更友好的方式就是,前端只需要传一个当前APP的版本号,后端根据前端传过来的版本号,自动匹配到对应的版本API接口。

3、接口考虑幂等性

所谓幂等: 多次调用方法或者接口不会改变业务状态,可以保证重复调用的结果和单次调用的结果一致

我们在开发中主要操作也就是CURD,其中读取操作和删除操作是天然幂等的,我们所关心的就是创建操作、更新操作。

创建操作一定是非幂等的因为要涉及到新数据的产生,而更新操作有可能幂等有可能非幂等,这个要看具体业务场景。

有关接口如何保证幂等之前有写过6种常见解决办法:

接口的幂等性如何设计?

4、接口考虑防止重复请求

防重和幂等的概念其实很像,上面保证幂等的解决方案同样适用于防止重复请求。

它们的区别在于:

防重

防重的目的是防止重复数据的产生,比如新增接口,用户快速点击两次,如果没做防重,就会产生重复数据。

幂等

比如请求多次,只有第一次请求才会做数据处理,后面的请求不会产生数据改变,例如退款接口,第一次退款成功后,后面的请求,不会再次退款成功。

5、提高接口的响应时间

1)、数据库查询尽量走索引,优化查询速度。

2)、是否考虑需要添加缓存:本地缓存、redis缓存、es存储等等。

3)、是否考虑走异步操作、多线程、mq消息队列等一些方式,提高接口的响应速度。

6、接口限流控制

限流是为了更好的维护系统稳定性。如果说我们把接口提供出来给第三方系统用,那么这个时候接口的限流是非常有必要的。

一方面,限流可以防止接口被刷,造成不必要的服务层压力,另一方面,是为了防止接口被滥用。

可以使用redis进行接口调用次数统计,ip+接口地址作为key,访问次数作为value,每次请求value+1,设置过期时长来限制接口的调用频率。

7、黑白IP白名单

ip白名单是指将接口的访问权限对部分ip进行开放。这样就能避免其他ip进行访问攻击。

ip黑名单是设置不能通过的ip,黑名单以外的ip都能通过。

显然白名单比黑名单限制的要更多一些。

设置ip白名单比较麻烦的一点就是当你的客户端进行迁移后,就需要重新联系服务提供者添加新的ip白名单。

设置ip白名单的方式很多,除了传统的防火墙之外,spring cloud alibaba提供的组件sentinel也支持白名单设置。

为了降低api的复杂度,推荐使用防火墙规则进行白名单设置。

8、敏感数据脱敏

在接口调用的过程中,可能会涉及一些敏感字段比如:身份证号银行卡号地址手机号等等,这些数据通常需要做脱敏处理,比如手机号15912345678脱敏后显示159****5678。

9、请求接口的先决条件-token

它的大致流程是这样的,首先用户登陆成功后,生成一个token返回前端。同时后端将这个token作为key, value为用户信息存入redis缓存中。

那么以后访问其它接口的时候,在请求头带上这个token请求接口,后端通过拦截器拦截该接口,做校验看redis是否存在该key,如果不存在直接返回,用户未登陆!

当然有些接口想不登陆就可以访问比如注册接口,那将拦截器过滤这些接口就可以了。

10、记录接口请求日志

关键的接口一定要有日志,入参日志出参日志异常日志,这样一旦出现问题,我们可以通过查看日志一下子定位问题所在。

当然如果觉得这样打印的日志太多了,我们可以设置日志级别,在特定的情况下才打印该种级别日志。

如果是我们把接口提供出来给第三方系统用,那么每一次请求过来,我们都要记录好请求入参出参、包活它们给的唯一标识ID.如果第三方反馈有问题,只要给到我们此次请求的唯一标识ID,我们通过这个ID,查询它这一次请求的完整链路,这样一来方便排查定位问题,二来如果不是我们接口的问题,日志也是证据,不用在扯皮了。

11、调用第三方接口要考虑异常、超时、重试

不论是我们将接口提供给第三方还是说我们请求第三方接口,我们所需考虑的都要多点,调第三方接口首先考虑就是超时、异常、重试。

超时

我们没法确定第三方接口多久返回,所以我们应该设置个超时时间,保证我们这边接口不被卡死。

异常

是接口都有可能出现异常,调第三方接口异常了,日志肯定要有,同时要考虑是重试还是告警处理。

重试

调第三方接口如果失败了,可能是网络的原因,需不需要重试?重试几次都是需要考虑的。

12、统一响应数据格式

在开发中,我们在定义接口时需要返回统一格式的响应体,响应数据会包含三个属性: 状态码(code),信息描述(message),响应数据(data)。

客户端可以根据状态码可以快速接口请求是否成功,如果成功则开始处理数据,如果失败则直接抛出message信息。

13、接口单一职责

单一职责,接口功能明确单一,不是为了省事,各种融于;在明确接口职责的条件下,尽量做到接口单一,即一个接口只做一件事,而非两件以上。

很多非资深接口设计者,在设计接口时,总认为接口所做的事越多,越牛叉,这是非常严重的错误认识。

14、接口文档的可读性

无论我们的接口设计得多么规范,多么易懂,我们都需要提供一份完整的api文档,同时我们还需要提供一些请求范例,这样用户在使用的时候才会更加清楚,也能避免一些错误的请求。



posted on 2022-11-10 18:54  雨点的名字  阅读(1044)  评论(1编辑  收藏  举报