什么是第三方 API?
首先要知道的是应用程序编程接口,也就是我们常说的“接口”。在项目内部,后端为前端提供接口。在外部,其他服务商为我们提供第三方接口。
当然第三方这个概念不是绝对的,如果我们有一个开放的平台,对外开放了接口,从别人的角度来看,我们的接口是第三方的接口,但是对于我们自己来说,就是开放的API。
API 规范
不管是我们自己开发的接口,还是第三方的接口,我们都需要遵循一定的设计规范,比如:
我们查阅微信商户平台接口规则文档,可以看到API规则描述,如:
在开发中我们通常会关注API的基本规则;至于数据的加密解密,请求签名以及验签等,官方的API中都集成了这些规则,可以帮助我们完成身份认证以及请求签名等。
封装第三方服务接口
当我们需要对接第三方API的时候,我们应该对第三方服务接口进行封装,这样不仅可以提高代码质量和开发效率,也方便后续的升级和维护。
我们以微信支付为例,分析一下在开发工作中如何封装第三方服务接口。
集成 SDK
为了减少开发工作量,集成SDK是最省时省力的方法,这里介绍一下微信支付服务器SDK:
<dependency>
<groupId>com.github.wechatpay-apiv3groupId>
<artifactId>wechatpay-apache-httpclientartifactId>
<version>0.4.8version>
dependency>
内容分割
整个第三方接口文档会有很多内容,但一般都是介绍接口的请求和响应。比如微信支付的订单主要包括接口描述、请求参数、响应参数、错误码等。因此,我们可以将项目代码分为:
同时微信支付API还有回调通知,比如支付通知,这里也单独划分一下:
除此之外,我们在开发时还需要考虑其他相关的类,比如工具类、配置类等等:
我们将上述内容归类到不同的包中,代码中的目录结构如下:
我们从配置类开始,因为这是开发前的一切,对于微信支付来说,我们需要用到的密钥、商户API证书、商户API私钥等支付相关的内容,都需要提前在商户平台申请和配置好。
以下是微信支付配置类的示例:
API
接下来是存放接口的常量类,有些url是完整的请求地址,有些是需要接参数的字符串模板,比如微信支付订单号查询订单,/v3/pay//id/{},我们可以按照官方的复制过来,也可以改成适用的代码,将{}改成%s。
以下是微信支付的示例:
,,
我们不建议使用Map来put或者get请求参数和响应数据,因为根据以往的开发经验,这样会让代码变得冗余冗长,也会造成代码阅读上的混乱。因此我们定义了、、、这些存储参数相关的实体类。
在查阅微信支付文档的时候会发现,不管是接口的请求参数还是响应参数,它们的数据体都是结构化的。比如下单的#%E8%AF%B7%E6%B1%82%E5%8F%82%E6%95%B0请求参数中,除了外层数据之外,还有嵌套的数据,其中又嵌套了数组类型的数据。代码片段如下:
{
"appid" : "wxd678efh567hg6787",
"mchid" : "1230000109",
"detail" : {
"cost_price" : 608800,
"goods_detail" : [
{
"merchant_goods_id" : "1246464644"
}
]
}
}
代码中我们遵循官方文档给出的数据结构,对实体类进行同样的编码,如果有嵌套数据,则会当做嵌套类处理。需要注意的是,无论嵌套多少层,都需要对每个类都实现序列化;同时将嵌套类修饰为静态,方便引用。
以下是订单请求参数实体类的示例:
就是客户端,就是业务代码中向第三方服务API发起请求的类,是向下向上的,跟工具类一样,里面定义了不同的静态方法,每个方法对应一个第三方API。
以下是微信支付客户端示例:
上面的#中,输入参数为,返回值是对应的接口。不过需要注意的是,并不是所有的第三方API都会返回结构化数据,比如微信小程序中获取小程序码。
返回参数说明如下:
❝
如果调用成功则直接返回图片的二进制内容,如果请求失败则返回JSON格式的数据。
此时方法的返回参数不能直接作为实体类,而应该由or接收然后返回给上层处理。例如微信小程序中获取无限小程序码的方法如下:
实用工具
Util用于存放工具类,比如用于HTTP请求、加解密、签名验证、证书管理等的工具类。通常第三方SDK中提供了这样的工具类,但是为了适配业务,有时候需要在这些工具类基础上自己封装一下。
以下是微信支付HTTP请求的工具类示例:
商务对接
当我们完成了第三方API的封装之后,我们就可以对接业务了。
控制层
这里我们以接驳微信支付的订餐业务为例,在支付流程中,当用户点击提交订单后,服务器生成订单并向微信发起预支付(即下单/APP下单/下单...),等待预支付成功后返回前端,前端调出支付面板,最终完成用户的支付。
以下是预付款接口示例:
服务层
在控制层中,预付费方式仅进行基本的流程控制,其核心业务(#)交由服务层处理,核心业务包括参数实体类的组装、客户端请求的调用(#)以及响应数据的处理。
业务代码如下:
总结
经过第三方服务API的封装以及业务对接的演示,我们可以看到业务中整个代码流程清晰顺畅,调用层次简洁,基本不涉及任何底层代码编码。 在业务实现中,无需担心签名、验签、证书等处理,真正让业务回归业务。