Api接口服务层

Api接口层称为接口服务层,负责对客户端的请求进行响应,处理接收客户端传递的参数,进行高层决策并对领域业务层进行调度,最后将处理结果返回给客户端。

接口参数规则配置

接口参数,对于接口服务本身来说,是非常重要的。对于外部调用的客户端来说,同等重要。对于接口参数,我们希望能够既减轻后台开发对接口参数获取、判断、验证、文档编写的痛苦;又能方便客户端快速调用,明确参数的意义。由此,我们引入了参数规则这一概念,即:通过配置参数的规则,自动实现对参数的获取和验证,同时自动生成在线接口文档。

一个简单的示例

假设我们现在需要提供一个用户登录的接口,接口参数有用户名和密码,那么新增的接口类和规则如下:

// 文件 ./src/app/Api/User.php
<?php
namespace App\Api;

use PhalApi\Api;

class User extends Api {

public function getRules() {
return array(
'login' => array(
'username' => array('name' => 'username'),
'password' => array('name' => 'password'),
),
);
}

public function login() {
return array('username' => $this->username, 'password' => $this->password);
}
}

当请求此接口服务,并类似这样带上username和password参数时:

/?s=User.Login&username=dogstar&password=123456

就可以得到这样的返回结果。

{"ret":0,"data":{"username":"dogstar","password":"123456"},"msg":""}

接口返回

回顾一下,在PhalApi中,掊口返回的结果的结构为:

{
"ret": 200, // 状态码
"data": {
// 业务数据
},
"msg": "" // 错误提示信息
}

正常情况下的返回

正常情况下,在Api层返回的数据结果,会在返回结果的data字段中体现。例如:

class Hello extends Api {

public function world() {
return array('title' => 'Hello World!');
}
}

对应:

{
"ret": 200,
"data": {
"title": "Hello World!"
},
"msg": ""
}

成功返回时,状态码ret为200,并且错误信息msg为空。

失败情况下的返回

对于异常情况,包括系统错误或者应用层的错误,可以通过抛出PhalApi\Exception系列的异常,中断请求并返回相关的错误信息。例如:

class Hello extends Api {

public function fail() {
throw new BadRequestException('签名失败', 1);
}
}

会得到以下结果输出:

{
"ret": 401,
"data": [],
"msg": "Bad Request: 签名失败"
}

扩展:返回JSONP、XML等其他格式

JSONP返回格式

如果需要支持JSONP返回格式,可以将 ​​./config/di.php​​中的以下代码注释去掉:

// 支持JsonP的返回
if (!empty($_GET['callback'])) {
$di->response = new \PhalApi\Response\JsonpResponse($_GET['callback']);
}

然后在请求时,传入回调函数的名称callback,即可返回JSONP格式。例如请求:

http://dev.phalapi.net/?s=Hello.World&callback=test

返回:

test({"ret":200,"data":{"title":"Hello World!"},"msg":""})

XML返回格式

如果需要返回XML格式,需要将​​\PhalApi\DI()->response​​切换到XML响应类,如:

$di->response = new \PhalApi\Response\XmlResponse();

然后,可看到请求的接口返回类似如下:

<?xml version="1.0" encoding="utf-8"?><xml><ret><![CDATA[200]]></ret><data><title><![CDATA[Hello World!]]></title></data><msg><![CDATA[]]></msg></xml>

其他返回格式

常用的返回格式有如上的JSON、JSONP、XML返回格式。如果需要返回其他的格式,你可以:

  • 1、实现\PhalApi\Response抽象中的formatResult($result)格式化返回结果
  • 2、重新注册\PhalApi\DI()->response服务

如果希望能由客户端指定返回格式,可通过参数来动态切换。

扩展:修改默认返回的ret/data/msg结构

对于默认返回的字段结构,源代码实现在PhalApi\Response::getResult()方法。相关代码片段如下:

abstract class Response {
public function getResult() {
$rs = array(
'ret' => $this->ret,
'data' => is_array($this->data) && empty($this->data) ? (object)$this->data : $this->data, // # 67 优化
'msg' => $this->msg,
);
if (!empty($this->debug)) {
$rs['debug'] = $this->debug;
}
return $rs;
}
}

如果需要修改默认的ret/data/msg,可以重载此方法,然后进行修改。值得注意的是,你可以基于现有的具体响应类进行继承重载。例如针对JSON的返回格式,先添加一个自己的扩展子类。例如只返回data部分:

<?php
// 新建 ./src/app/Common/MyResponse.php 文件

namespace App\Common;

use PhalApi\Response\JsonResponse ;

class MyResponse extends JsonResponse {
public function getResult() {
// 只返回data部分
$rs = parent::getResult();
return $rs['data'];
}
}

接着在 ./config/di.php 文件中重新注册​​$di->response​​服务为此新的响应类实例。例如:

$di->response = new \App\Common\MyResponse();

完成子类重载,以及response服务重新注册后,再次访问接口,就会看到返回的结果去掉了ret和msg部分。

例如,对于Hello World接口服务,原来返回是:

{"ret":200,"data":{"title":"Hello World!"},"msg":""}

现在,返回是(只返回data部分):

{"title":"Hello World!"}