likes
comments
collection
share

七个方面!API接口设计需要注意的问题

作者站长头像
站长
· 阅读数 16

前言

大家好,我是小郭,今天主要梳理一下API接口设计需要注意的问题。

七大方面

1. 接口隔离原则

接口隔离原则(Interface segregation principle,ISP):使用多个专门的接口,而不使用单一的总接口,即客户端不应该依赖那些它不需要的接口。

当我们在设计 API 的时候,应该尽量让每一个 API 只做一个职责的事情。

这样做的好处在于能保证 API 功能的简单易用性稳定性,一旦接口职责混在一起,就会造成接口间功能相互影响,造成牵一发而动全身的后果。

我们来看一个伪代码,有时候因为懒得去新增接口,直接在原来的接口上做新增类型的操作,如果有大量的用户进行更新用户信息的操作,是肯定就会给插入用户造成一定的影响。

@PostMapping
@ResponseBody
public boolean updateUser(User user){
 if (Objects.equals(1, user.optType)) { // 执行插入用户操作
     userServcie.save();
    } else if (Objects.equals(2, user.optType)){ // 执行更新用户操作
     userServcie.update(user.optType);
    }
 return true;
}

2. 命名通俗易懂

好的 API 设计应该给使用者提供一种简单、直观、一致的体验,让我们望文知义

在这一方面,阿里巴巴的编程规约给了我们很好的帮助,我在这里拿出来几个我们常见的问题

【强制】方法名、参数名、成员变量、局部变量都统一使用lowerCamelCase风格

正例:localValue/inputUserId

【强制】杜绝完全不规范的缩写,避免望文不知义

反例:AbstractClass“缩写”命名为AbsClass,降低代码的可读性

【推荐】为了达到代码自解释的目的,任何自定义编码元素在命名时,使用尽量完整的单词组合来表达。

正例:在JDK中,对某个对象引用的volatile字段进行原子更新的类名为 AtomicReferenceFieldUpdater

反例:常见的方法内变量为 int a;的定义方式

3. 使用更贴切方法的HTTP动词

编程世界通常来说有两种逻辑:“业务逻辑” 和 “控制逻辑”。

  • 业务逻辑。就是你实现业务需求的功能的代码,就是跟用户需求强相关的代码。比如,把用户提交的数据保存起来,查询用户的数据,完成一个订单交易,为用户退款等等,这些是业务逻辑
  • 控制逻辑。就是我们用于控制程序运行的非功能性的代码。比如,用于控制程序循环的变量和条件,使用多线程或分布式的技术,使用HTTP/TCP协议,使用什么样数据库,什么样的中间件等等,这些跟用户需求完全没关系的东西。

HTTP的动词(或是Method)是在协议头中,其主要用于控制逻辑。

方法描述幂等
GET用于查询操作,对应于数据库的 select 操作✔︎
PUT用于所有的信息更新,对应于数据库的 update 操作✔︎︎
DELETE用于更新操作,对应于数据库的 delete 操作✔︎︎
POST用于新增操作,对应于数据库的 insert 操作
HEAD用于返回一个资源对象的“元数据”,或是用于探测API是否健康✔︎
PATCH用于局部信息的更新,对应于数据库的 update 操作
OPTIONS获取API的相关的信息。✔︎

RESTFUL API 的优势

  1. 无状态,服务器不需要记住客户端的状态
  2. 可缓存性,提高客户端的响应速度
  3. 分层系统,在客户端与服务器端之间增加一个中间层

很多时候要分析一下业务语义,不要机械地通过数据库的CRUD来对应这些动词,如果都使用POST在进行一起的操作,我们就根本无法判断这个接口是做什么的,以及他是否是幂等的。

4. 幂等性问题

什么是幂等?

就是当一个操作多次执行所产生的影响均与一次执行的影响相同。

  • POST 用于新增加数据,比如,新增一个交易订单,这肯定不能是幂等的
  • DELETE 用于删除数据,一个数据删除多次和删除一次的结果是一样的,所以,是幂等的
  • PUT 用于全部数更新,所以,是幂等的。
  • PATCH用于局部更新,比如,更新某个字段 cnt = cnt+1,明显不可能是幂等操作。

API 设计中做到接口幂等的五种方式

  1. 天然幂等,利用数据库查询一次或者多次结果都相同
  2. 利用数据库的唯一ID
  3. 上锁,分布式环境中采用分布式锁,如RedisLock、ZK
  4. Source + Token,这两个字段做了联合的唯一索引,同时记录不同客户端使用 API 的调用情况
  5. 使用有限状态机,在进行操作之前,先查询查来目前的数据状态是否符合接下来的流程,通过对状态的扭转控制来确保幂等

5. 少创造Erroe Code

我们知道自定义的风险就在于各自理解可能有偏差,进而导致业务更大的混乱。

比如,当使用方在使用 HTTP API 时,获得了一个 404 错误码(在 HTTP 中是未找到资源的错误),而你恰好也定义了 404 错误码(假设代表接口数据未找到),结果必然出现冲突。

所以 API 的使用方是否可以清晰地理解错误信息,是非常重要的

{
	"code": "10017",
	"data": null,
	"error": false,
	"errorClass": null,
	"errorStack": null,
	"failure": true,
	"message": "用户名或密码不正确",
	"success": false,
	"violationItems": null
}

{
	"code": "200",
	"message": "成功!",
	"data": {},
	"success": true
}

6. 安全策略

内部:对接受的数据要有足够的验证,考虑输入与输出数据的准确性,出现错误要能及时抛出异常并进行异常处理

外部:防护产品,限流措施

7. 版本管理

  1. 在接口中使用版本号

在同一服务 API 中公开两个版本,比如在接口中使用 V1 和 V2

和我们常说的蓝绿发布很像,这样子维护两个版本必然会增加我们的成本,蓝绿部署要求在升级过程中,同时运行两套程序,对硬件的要求就是日常所需的二倍,比如日常运行时,需要10台服务器支撑业务,那么使用蓝绿部署,你就需要购置二十台服务器。

  1. 通过网关根据路由规则进行请求分发

按照规则请求分发,常说的灰度发布很像,新版本测试通过则渐进切换到新版本中,未通过则回滚老版本

总结

七个方面!API接口设计需要注意的问题

转载自:https://juejin.cn/post/7158334823697186852
评论
请登录