API接口设计

总结一下API接口开发过程中的注意事项

1、跨平台性

所谓跨平台是指我们的接口要能够支持不同的终端,比如android、ios、windowsphone以及桌面软件、网站等。如:不同的终端每页显示的记录数不同


采用通用的解决方案,比如通信协议就采用最常用的HTTP/RPC协议,如果是即时通信,可以采用开放的XMPP协议,做游戏的可以采用可靠的TCP协议,除非TCP不够用了,再采用定制的UDP协议。数据交换采用xml或者json格式或者webservice等等。总之,要达到的目标就是让不同的端能够很方便的使用你的接口。

function ajaxJson($data, $jsonCallBack = '', $fromCode = "UTF-8") {
    mb_convert_variables("UTF8", $fromCode, $data);
    header("Cache-Control: no-cache, no-store, must-revalidate, max-age=-1");
 
    $result['data'] = $data['data'];
    $result['code'] = isset($data['msg']) ? sprintf('%06s', $result['code']) : "000000";
    $result['msg'] = isset($data['msg']) ? $data['msg'] : "sucess";
    $outPut = json_encode($result, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
    if ('' != $jsonCallBack) {
        $outPut = $jsonCallBack . '(' . $outPut . ')';
    } else {
        header("Content-Type: application/json; charset=utf-8");
    }
    exit($outPut);
}
 
function apiReturn($data, $type = 'JSON') {
    $args = func_get_args();
    if ($args > 2) { // 外部接口调用,有code,msg
        $info = array();
        $info['data'] = $data;
        $info['code'] = sprintf('%06s', array_pop($args));
        $message = array_pop($args);
        $info['msg'] = ($type == $message) ? "success" : $message;
        $data = $info;
    }
    //内部程序调用
    if (strtoupper($type) == 'JSON') {
        // 返回JSON数据格式到客户端 包含状态信息
        header("Content-Type: application/json; charset=utf-8");
        exit(json_encode($data));
    } elseif (strtoupper($type) == 'XML') {
        // 返回xml格式数据
        header('Content-Type:text/xml; charset=utf-8');
        exit(XML::build($data));
    } elseif(strtoupper($type) == 'EVAL'){
        header('Content-Type:text/html; charset=utf-8');
        exit($data);
    }
}
2、良好的响应速度

接口应该以最快的速度将数据返回给请求者,要达到的目标就是快。一个页面,秒开最好,超过三秒就需要找找原因了。数据量按需分配,APP客户端需要什么数据就返回什么数据,过多的数据量影响处理速度,最重要的是影响传输效率

3、接口要为移动客户端考虑

比如,在移动端里,下拉刷新和上拉加载更多是很常见的功能,如果接口仍然按照传统的web思路,只提供按页读取的话,就会造成移动端的额外的数据请求和计算。 这时,接口就应该针对这两种类型的操作提供额外的支持。

4、考虑移动端的网络情况和耗电量
如果让我们说出哪类app比较好,可能还不大好说,但是如果让我们说出哪些app很差,我们肯定会说出那些体积很大、占用内存多、界面很卡、费电的app 不好。对于网络情况,接口应该具备为不同的网络提供不同的内容的能力如果我们能够知道用户的网络情况,只有在wifi的情况下才给用户传输封面图、缩略图 之类的,
是不是可以帮用户节省很多流量呢

 5、通用的数据交换格式

目前,对于接口和客户端的数据交换格式,基本上就是三种,xml和json和webservice,而现在使用json的应该占大多数最麻烦的就是处理Date类型,因为JSON本身没有Date类型,因此,JSON库将Date类型的数据序列化时会转为String。这时,不同环境, 不同平台,以及用不同的JSON解析库,转换后的结果经常会不同。比如,你在开发机上可能得到的结果是”2016-1-1 17:11:11”,但放到服务器后结果却变成了“Jan 1,2016 5:11:11 PM” ,客户端进行反序列化时无疑会失败。后来,我取消了所有Date类型,统一采用时间戳表示,就再没有转化的烦恼了。 另外,接口的开发人员有时候会将一些数据错误地转换为了String,导致客户端使用时因类型错误而异常。例如,本来是数字的1,被转成 了"1",客户端做运算时就会出错,或用switch判断时也会出错,或其他无法转换的情况发生时;例如,为空时JSON正确地表示应该是null,但如 果转为了String就变成了"null",那问题就来了,我遇到的因为这个错误的转换导致的程序奔溃已经好几次了,第一次的时候,查了一整天才定位到问题所在

6、接口统计功能

在做PC端网站的时候,我们都会给我们的网站加上个统计功能,要么自己写统计系统,要么使用第三方的比如GA。移动端接口API则需要我们自己实现统计功能,这时就需要我们尽可能多的收集客户端的信息,除了传统的IP、User-Agent之外,还应该收集一些移动 相关的信息,比如手机操作系统,是android还是ios,都是什么版本,用户使用的网络状况,是2G、3G、4G还是WIFI。客户端APP是什么版 本信息。

7、客户端与服务端的肥瘦平衡

在移动开发中,由于客户端的修改会很费时费力,特 别是IOS应用还要经过Apple审核,另外,当前IOS开发人员、Android开发人员的人工成本普遍较高,人才紧缺,基于这两点,能在服务器端实现 的功能就不要放在客户端,毕竟服务器端程序的修改要比客户端方便、灵活、快捷的多。

8、隐式用户与显式用户

显式用户指的是,APP程序中有用户系统,一个username、password正确的合法用户,称之为显式的用户,通常显式用户都需要注册,登录以后能完成一些个人相关的操作。隐式用户指的是,APP程序本身就没有用户系统,或者一个在没有登录的情况下,使用我们APP的用户。在这种情况下,可以通过客户端生成的UDID来标识一个用户。有了用户信息,我们就能够了解不同用户的使用习惯,而不仅仅是全体用户的一个整体的统计信息,有了这些个体的信息之后,就可以做一些用户分群、个性化推荐之类的事情。

9、安全问题

设计API第一个需要考虑的是API的安全机制。我负责的上一个项目,因为API的安全问题,就被人攻击了两次。之后经过分析,主要存在两个漏洞: 一是因为缺少对调用者进行安全验证的方式,二是因为数据传输不够安全。那么,制定API的安全机制,主要就是为了解决这两个问题:
保证API的调用者是经过自己授权的App;
保证数据传输的安全。
第一个问题的解决方案,我主要采用设计签名的方式。对每个客户端分别分配一个AppKey和AppSecret。需要调用API时,将AppKey加入请求参数列表,并将AppSecret和所有参数一起,根据某种签名算法生成一个签名字符串,然后调用API时把该签名字符串也一起带上。服务端收到请求之后,根据请求中的AppKey查询相应的AppSecret,按照同样的签名算法,也生成一个签名字符串,当服务端生成的签名和请求带过来的签名一致的时候,那就表示这个请求的调用者是经过自己授权的,证明这个请求是安全的。而且,每个端都有一个Key,也方便不同端的标识和统计。为了防止AppSecret被别人获取,这个AppSecret一般写死在代码里面。另外,签名算法也需要有一定的复杂度,不能轻易被别人破解,最好是采用自己规定的一套签名算法,而不是采用外部公开的签名算法。另外在参数列表中再加入一个时间戳,还可以防止部分重放攻击。如签名算法http://hudeyong926.iteye.com/blog/2287954
第二个问题的解决方案,主要就是采用 HTTPS了。HTTPS因为添加了SSL安全协议,自动对请求数据进行了压缩加密,在一定程序可以防止监听、防止劫持、防止重发,主要就是防止中间人攻击。因此,为了安全考虑,建议对SSL证书进行强校验,包括签名CA是否合法、域名是否匹配、是不是自签名证书、证书是否过期等。
接口安全:OAuth认证,IP白名单,VPN通道。接口的安全工作不能马虎,暴力破解啊、SQL Injection啊、伪造请求和数据啊、重复提交啊也要考虑到。如果数据特别敏感,可以考虑采用SSL/TLS等加密传输,或者客户端、服务器端约定一个加密算法和密钥(rsa),对来往传输的数据进行加密解密。
10、良好的接口说明文档和测试程序

接口文档要清晰、明了,包含多少个接口,每个接口的地址、参数、请求方式、数据交换格式、参数是否必填、编码格式UTF8,返回值等都要写清楚。接口测试程序,有条件的话,也可以提供,方便前后端的调试


11、版本的维护
随着业务的变化,客户端APP和服务器端API都会发生变化,增加新的功能,修改已有的功能,
增加功能还好说, 如果是接口需要修改,那么就面临着同一个接口要同时为不同版本的客户端服务的问题。
因此,服务器端接口也要做好相应的版本维护。主版本更新可以把版本号放入API的URL中/api-v2来指出所使用的API版本。次要版本的修改是通过客户在API调用时发起请求的HTTP头部做指定的头部的版本元素看起来是这样的:Element-Version: 1

12、接口数据、状态
接口必须提供明确的数据状态信息,不管是成功的,还是失败的,都必须返回给APP客户端。
13、接口、参数命名准确。
无论是接口还是参数,命名都应该有意义,让人一目了然。
14、推送接口的设计。
对于某些数据更新后,第三方的数据要保持通过更新(insert,update),可以采用推送接口将最新的数据推送第三方。优点:第三方不需要高频度的轮询查询去更新,减轻服务器压力。(第三方需提供通知地址,即接口服务端,我方更新后调用即可)

15、高并发考虑接口的限流,减轻服务器压力。

实现访问者ip在一定的时间内只能访问次数.

接口调试技巧前提必须放在外网上
1》服务端return 调试信息,客户端调用并显示结果,

2》在服务端将结果保存成文件在打开文件查看,即日志型调试(或建临时表放在数据库表里)

考虑突然断网或接口信息返回超时异常情况的业务处理(先扣金额再调用接口,如有问题,金额原路返回)

支付宝

$alipaySubmit = new AlipaySubmit($alipay_config);
$url = $alipaySubmit->alipay_gateway_new.$alipaySubmit->buildRequestParaToString($parameter);
header("Location: {$url}");
 

发布了139 篇原创文章 · 获赞 8 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_37003559/article/details/103887573