在进行API开发的时候,需要事先定义好app与server交互的数据格式,这样前端人员与服务端人员才能够事先决定好如何获取数据、如何解析数据、如何传输协议。
在我看来目前接口协议无外乎这三种情况:
1. json数据进行交互
2. xml数据进行交互
3. 自定义数据格式交互
自定义数据格式进行前后端的数据交互,需要花费较大的精力,而且需要很有经验的人设计的协议才会确保各个平台的兼容以及良好的可阅读性。并且解析、封装都需要自己来用代码实现,很多第三方库都没办法用上。因为这里我不进行讨论。主要说说json与xml作为交互数据。
我在我的response中封装了json与xml。客户端可以根据自己的需要进行选择是获取json数据还是xml。指定方法是在请求的url中指定format=json/xml。这里为了程序的健壮,我会默认指定一种数据格式的返回,也就是如果客户端没有或者忘记设置format时,默认返回json数据。
**json数据的封装,在php中用json来进行数据交互是非常方便。实现代码:**
private static function jsonSucEncode($code, $msg, $datas){
if(!is_numeric($code)){
return ‘‘;
}
$ret = array(
‘succode‘ => $code,
‘sucmsg‘ => $msg,
‘datas‘ => $datas,
);
echo json_encode($ret);
}
$code表示返回的状态码,这个状态码应该在文档中进行说明含义,并事先定义好
$msg表示返回的信息,我觉得这个字段是有必要的,至少方便客户端开发人员进行错误定位。备注:我最开始就没有设计这个字段,而只是设计了$code这个状态吗,前端人员每次都要到文档中进行查看这个状态码是什么含义,很影响开发速度。
$datas:这个就是返回给前端的业务数据了。
然后使用json_encode()对这个数据编码后,就是json数据了。
xml数据的封装相对来说比较麻烦,方法有很多,我使用的是用字符串进行拼接:
private static function xmlSucEncode($code, $msg, $datas){
if(!is_numeric($code)){
return ‘‘;
}
$ret = array(
‘succode‘ => $code,
‘sucmsg‘ => $msg,
‘datas‘ => $datas,
);
echo self::xml($ret);
}
private static function xml($datas){
header("Content-Type:text/xml");
$xml = "<?xml version=‘1.0‘ encoding=‘UTF-8‘?>";
$xml .= ‘<root>‘;
$xml .= self::createXML($datas);
$xml .= ‘</root>‘;
return $xml;
}
private static function createXML($datas){
$xml = $attr = "";
foreach ($datas as $k=>$v){
if(is_numeric($k)) {// 如果k是数字,则将其作为一个属性来使用
$attr = " id=‘{$k}‘";
$k = "item";
}
$xml .= "<{$k}{$attr}>";
$xml .= is_array($v) ? self::createXML($v) : $v;
$xml .="</{$k}>";
}
return $xml;
}
然后现在xml数据、json数据的封装方式都有了,此时应该提供一个统一的接口,供前台来调用,通过参数进行控制,返回xml数据还是json数据。而不是这样子抛出去两个接口,让客户端的人自己选择。同时抛出去两个接口还有一个问题:如果要更换,更换的就是接口的名称以及它的参数。
这里我定义的统一接口:
public static function sendEncode($code, $msg, $state, $datas=array(), $type=self::JSON){
// 如果请求参数设置了请求类型,则返回请求的类型,否则使用参数中的类型,默认为json
$type = isset($_GET[‘format‘]) ? $_GET[‘format‘] : $type;
switch ($type){
// json格式数据
case self::JSON :
if($state == self::SUCCESS){
self::jsonSucEncode($code, $msg, $datas);
}else{
self::jsonErrEncode($code, $msg);
}
exit;
break;
// xml数据
case self::XML :
if($state == self::SUCCESS){
self::xmlSucEncode($code, $msg, $datas);
}else{
self::xmlErrEncode($code, $msg);
}
exit;
break;
// 其他数据格式请求
default:
self::jsonErrEncode(self::ILLEGAL_CODE, self::ILLEGAL_MSG);
exit;
break;
}
}
这里边有一些常量,我是定义在response这个类里边的,这里就不写出来了,相信大家应该可以猜到。如果有人需要这个工具的完整实现方式,可以留下邮箱,我发给您,共同学习进步。
第五篇我会分享一下我在接口设计中APP注册这一部分的实例。