api接口设计

健壮性

  1. 对外提供的接口,最好支持幂等性,即相同的请求重复调用,服务端的操作应该只有一次,并且每次返回的结果应该是一样的。
    一般的做法是要求客户端在每次调用的时候带上唯一键,服务端第一次正常处理,并缓存唯一键和结果,后面再有重复调用,即可直接获取缓存结果返回。
    如果客户端没有唯一键的条件,也可以要求传时间戳,用时间戳作为唯一键。
  2. 对外的接口,粒度能细就细,最好不要是那种入参是type,然后服务端根据type类型返回不同的数据,这样容易被调用方猜到一些服务端不想暴漏的内容。
    举个例子,比如你要对外提供字典接口。 你的service方法是入参type, type=country,就返回所有国家字典;
    type=currency,就返回所有币种字典。
    其实你只想对外暴漏这两个功能,但其实你的service还支持type=company,就返回所有公司,
    这个你是不想对外暴漏的,但有可能会被调用方猜到,从而获取了隐私数据。
    所以这种情况,就应该把接口拆开,比如获取国家就是一个接口,获取币种就是另外一个接口。
  3. 接口的入参,最好是包好的dto,这个不用多说,接口升级的时候,不会影响到用旧版本的客户端,便于扩展。
  4. 接口的出参,尽可能的少,没用的字段一定不要加,因为考虑到以后接口维护的时候,加字段好加,减字段可不好减。
  5. 接口的出参,服务不要把异常直接抛出来,一定要加全局异常捕获,明确指定不同类型的出参码,比如调用错误是什么,参数错误是什么等等。
  6. 单一职责,一个接口应该是专门给一个功能或者一类特定功能用的,避免接口复用,这个也是扩展性问题。
  7. 命名要统一,一定要有全局意识。比如所有的查询都是find开头,所有的查列表都是以list结尾,所有的分页都是currentPage+pageSize等等
  8. 命名要准确,随便用汉字拼音首字母命名都是一种不负责任的做法

安全性

  1. 上面有提到用时间戳作为请求唯一键,可以做幂等。其实用时间戳,还有个好处,就是可以判断是不是截取url的恶意调用。
    因为我们可以判断当前时间和时间戳的间隔,如果大于某个值,比如大于5秒,我们就判定这个url无效。 这样可以有效的抵挡一部分的DOS攻击。
  2. 如果调用方很确定,并且数量不多的话,直接配置ip白名单,简单高效。
  3. 再复杂的设计,比如签名验证,但个人觉得这个普通场景没什么必要,增加复杂度,
    但安全度极高的场景,是必加的,而且至少要token+时间戳的签名,token是客户端的身份证明。