想要设计一个良好的接口至少要考虑这 14 点!
入参合法性校验
接口的版本控制
接口考虑幂等性
接口考虑防止重复请求
提高接口的响应时间
接口限流控制
黑白 IP 白名单
敏感数据脱敏
请求接口的先决条件-token
记录接口请求日志
调用第三方接口要考虑异常、超时、重试
统一响应数据格式
接口单一职责
接口文档的可读性
在我们日常开发中设计一个接口的步骤大致如下:
Controller 层定义接口 url、请求方式、入参、统一格式的出参。然后在 Service 层去定义接口和实现类,这样一个接口就算完成了。
当然我们还需要考虑很多东西,比如接口的规范性、安全性,可扩展性、稳定性等等。
这篇文就来整理下 设计一个良好的接口需要考虑哪些点呢?
1、入参合法性校验
入参的合法性校验是一个良好的接口必备的前提条件,通过入参的校验我们可以过滤掉许多无效的请求,提高系统的稳定性。
我们可以将入参合法性校验分为: 常规性校验 和 业务校验;
所谓的常规性校验包括:token 校验、必填校验、长度校验、类型校验等等;
业务校验也就是特定业务场景下的校验:比如用户商品下单接口,那么下单金额一定要大于 0;
有关参数校验之前写过一篇文章:Spring Boot 实现各种参数校验
2、接口的版本控制
我们在开发小程序或者 app 的时候,都需要对版本进行升级,而提前设计好版本,可以避免因为升级导致旧的服务无法正常工作,我们要保证在升级的时候,新旧版本的服务都能正常运转。
多版本控制现在比较常见的方式有:url标识版本
, header标识版本
, params标识版本
3 种方式。
这里举 url 为例。接口定义:
后台接口:
基于 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 文档,同时我们还需要提供一些请求范例,这样用户在使用的时候才会更加清楚,也能避免一些错误的请求。
原文:https://www.cnblogs.com/qdhxhz/p/16655103.html
如果感觉本文对你有帮助,点赞关注支持一下,想要了解更多 Java 后端,大数据,算法领域最新资讯可以关注我公众号【架构师老毕】私信 666 还可获取更多 Java 后端,大数据,算法 PDF+大厂最新面试题整理+视频精讲
评论