跳到主要内容

如何优雅的接口

· 阅读需 9 分钟
ahKevinXy

from

签名

接口请求将 请求参数 + 时间戳 + 秘钥 拼接成一个字符串,通过md5 等hash 算法,生成一个sign

加密

sm2 国密

rsa 加密

ip 白名单

为了 限制 api 接口的安全性,防止 接口签名或加密被破解,攻击者 可以在自己的服务器上请求改接口

只有 在白名单中的ip地址,才能成功请求api接口,否则返回无权限

这时候就需要增加web防火墙了,比如:ModSecurity (todo 研究)等。

限流

限流方法有三种:

  1. 对请求ip做限流 : 策略制定
  2. 对请求接口做限流
  3. 对请求用户做限流

我们在实际工作中,可以通过nginx,redis或者gateway实现限流的功能。

参数校验

我们需要对API接口做参数校验,比如:校验必填字段是否为空,校验字段类型,校验字段长度,校验枚举值等等。

这样做可以拦截一些无效的请求。

统一返回值

我之前调用过别人的API接口,正常返回数据是一种json格式,比如:

签名错误返回的json格式:

{
"code":1001,
"message":"签名错误",
"data":null
}


没有数据权限返回的json格式:

{
"rt":10,
"errorMgt":"没有权限",
"result":null
}

统一封装异常

我们的API接口需要对异常进行统一处理。

不知道你有没有遇到过这种场景:有时候在API接口中,需要访问数据库,但表不存在,或者sql语句异常,就会直接把sql信息在API接口中直接返回。

返回值中包含了异常堆栈信息数据库信息错误代码行数等信息。

因此非常有必要对API接口中的异常做统一处理,把异常转换成这样:

{
"code":500,
"message":"服务器内部错误",
"data":null
}

我们可以在gateway中对异常进行拦截,做统一封装,然后给第三方平台的是处理后没有敏感信息的错误信息。

请求日志

我们需要把API接口的请求url、请求参数、请求头、请求方式、响应数据和响应时间等,记录到日志文件中。

当然有些时候,请求日志不光是你们公司开发人员需要查看,第三方平台的用户也需要能查看接口的请求日志。

这时就需要把日志落地到数据库,比如:mongodb或者elastic search,然后做一个UI页面,给第三方平台的用户开通查看权限。这样他们就能在外网查看请求日志了,他们自己也能定位一部分问题。

幂等设计

第三方平台极有可能在极短的时间内,请求我们接口多次,比如:在1秒内请求两次。有可能是他们业务系统有bug,或者在做接口调用失败重试,因此我们的API接口需要做幂等设计。

也就是说要支持在极短的时间内,第三方平台用相同的参数请求API接口多次,第一次请求数据库会新增数据,但第二次请求以后就不会新增数据,但也会返回成功。

我们在日常工作中,可以通过在数据库中增加唯一索引,或者在redis保存requestId和请求参来保证接口幂等性。

限制记录条数

对于对我提供的批量接口,一定要限制请求的记录条数

如果请求的数据太多,很容易造成API接口超时等问题,让API接口变得不稳定。

通常情况下,建议一次请求中的参数,最多支持传入500条记录。

如果用户传入多余500条记录,则接口直接给出提示。

压测

上线前我们务必要对API接口做一下压力测试,知道各个接口的qps情况。

我们在工作中可以用jmeter或者apache bencab对API接口做压力测试。

异步处理

一般的API接口的逻辑都是同步处理的,请求完之后立刻返回结果。

但有时候,我们的API接口里面的业务逻辑非常复杂,特别是有些批量接口,如果同步处理业务,耗时会非常长。

这种情况下,为了提升API接口的性能,我们可以改成异步处理。

在API接口中可以发送一条mq消息,然后直接返回成功。之后,有个专门的mq消费者去异步消费该消息,做业务逻辑处理。

直接异步处理的接口,第三方平台有两种方式获取到。

第一种方式是:我们回调第三方平台的接口,告知他们API接口的处理结果,很多支付接口就是这么玩的。

第二种方式是:第三方平台通过轮询调用我们另外一个查询状态的API接口,每隔一段时间查询一次状态,传入的参数是之前的那个API接口中的id集合。

数据脱敏

有时候第三方平台调用我们API接口时,获取的数据中有一部分是敏感数据,比如:用户手机号、银行卡号等等。

这样信息如果通过API接口直接保留到外网,是非常不安全的,很容易造成用户隐私数据泄露的问题。

这就需要对部分数据做数据脱敏了。

完整的接口文档

说实话,一份完整的API接口文档,在双方做接口对接时,可以减少很多沟通成本,让对方少走很多弯路。

接口文档中需要包含如下信息:

  1. 接口地址
  2. 请求方式,比如:post或get
  3. 请求参数和字段介绍
  4. 返回值和字段介绍
  5. 返回码和错误信息
  6. 加密或签名示例
  7. 完整的请求demo
  8. 额外的说明,比如:开通ip白名单

接口文档中最好能够统一接口和字段名称的命名风格,比如都用驼峰标识命名。

统一字段的类型和长度,比如:id字段用Long类型,长度规定20。status字段用int类型,长度固定2等。

统一时间格式字段,比如:time用String类型,格式为:yyyy-MM-dd HH:mm:ss

接口文档中写明AK/SK和域名,找某某单独提供等。