接口响应与在线调试

对于接口响应,PhalApi默认使用了HTTP+JSON。通过HTTP/HTTPS协议进行通讯,返回的结果则使用JSON格式进行传递。正常情况下,当接口服务正常响应时,如前面的Hello World接口,可能看到以下这样的响应头部信息和返回内容。

HTTP/1.1 200 OK
Content-Type: application/json;charset=utf-8... ...{"ret":200,"data":{"title":"Hello World!"},"msg":""}

而当接口项目抛出了未捕捉的异常,或者因PHP语法问题而出现Error时,则没有内容返回,并且得到一个500的响应状态码。类似如下:

HTTP/1.1 500 Internal Server Error

响应结构 data-ret-msg

回顾一下默认接口服务返回的内容。类似如下:

{"ret": 200,"data": {"title": "Hello World!","content": "PHPer您好,欢迎使用PhalApi!","version": "2.0.0","time": 1499477583},"msg": ""
}

ret字段是返回状态码,200表示成功;data字段是项目提供的业务数据,由接口开发人员定义;msg是异常情况下的错误提示信息。下面分别说之。

业务数据 data

业务数据data为接口和客户端主要沟通对接的数据部分,可以为任何类型,由接口开发人员定义。但为了更好地扩展、向后兼容,建议都使用可扩展的集合形式,而非原生类型。也就是说,应该返回一个数组,而不应返回整型、布尔值、字符串这些基本类型。

业务数据主要是在Api层返回,即对应接口类的方法的返回结果。如下面的默认接口服务?s=Site.Index的实现代码。

<?php
namespace App\Api;use PhalApi\Api;class Site extends Api {public function index() {return array('title' => 'Hello World!','content' => \PhalApi\T('Hi {name}, welcome to use PhalApi!', array('name' => $this->username)),'version' => PHALAPI_VERSION,'time' => $_SERVER['REQUEST_TIME'],);}

实际上,具体的业务数据需要一段复杂的处理,以满足特定业务场景下的需要。Api层需要与Domain层和Model层共同协作,完成指定的功能。这里暂且知道接口结果是在Api层返回,对应接口类成员方法返回的结果即可。

返回状态码 ret

返回状态码ret,用于表示接口响应的情况。参照自HTTP的状态码,ret主要分为四大类:正常响应、重定向、非法请求、服务器错误。

分类 ret范围 基数 说明
正常响应 200~299 200 表示接口服务正常响应
重定向 300~399 300 表示重定向,对应异常类RedirectException的异常码
非法请求 400~499 400 表示客户端请求非法,对应异常类BadRequestException的异常码
服务器错误 500~599 500 表示服务器内容错误,对应异常类InternalServerErrorException的异常码

正常响应时,通常返回ret = 200,并且同时返回data部分的业务数据,以便客户端能实现所需要的业务功能。

值得注意的是,抛出的异常应该继承于PhalApi\Exception类,并且构造函数的第一个参数,是返回给客户端的错误提示信息,对应下面将讲到的msg字段。第二个参数是返回状态码的叠加值,也就是说最终的ret状态码都会在400的基数上加上这个叠加值,即:401 = 400 + 1。

例如,常见地,当签名失败时可以返回一个401错误,并提示“签名失败”。

<?php
namespace App\Api;use PhalApi\Api;
use PhalApi\Exception\BadRequestException;class Hello extends Api {public function fail() {throw new BadRequestException('签名失败', 1);}
}

会得到以下结果输出:

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

错误提示信息 msg

当接口不是正常响应,即ret不在2XX系列内时,msg字段会返回相应的错误提示信息。即当有异常触发时,会自动将异常的错误信息作为错误信息msg返回。

如何设置JSON中文输出?

默认情况下,输出的中文会被转换成Unicode,形如\uXXXX,如:

"content":"PHPer\u60a8\u597d\uff0c\u6b22\u8fce\u4f7f\u7528PhalApi\uff01"

虽然不影响使用,但不便于查看。如果需要不被转码,可以使用JSON_UNESCAPED_UNICODE选项进行配置。重新注册DI()->response并指定配置选项。例如可以:

$di->response = new \PhalApi\Response\JsonResponse(JSON_UNESCAPED_UNICODE); // 中文显示

设置后,重新请求,将会看到:

"content":"PHPer您好,欢迎使用PhalApi!"

类似地,还可以设置更多其他的选项,如追加强制使用对象格式:

$di->response = new \PhalApi\Response\JsonResponse(JSON_UNESCAPED_UNICODE | JSON_FORCE_OBJECT); // 中文显示 且 强制对象格式

扩展:如何使用其他返回格式?

除了使用JSON格式返回外,还可以使用其他格式返回结果。

例如在部分H5混合应用页面进行异步请求的情况下,客户端需要服务端返回JSONP格式的结果,则可以这样在DI配置文件./config/di.php中去掉以下注释。

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

目前,PhalApi 2.x 已经支持的响应格式有:

响应格式 实现类
JSON格式 PhalApi\Response\JsonResponse
JSONP格式 PhalApi\Response\JsonpResponse
XML格式 PhalApi\Response\XmlResponse
控制台格式 PhalApi\Response\ExplorerResponse

当需要返回一种当前PhalApi没提供的格式,需要返回其他格式时,可以:

  • 1、实现抽象方法PhalApi\Response::formatResult($result)并返回格式化后结果
  • 2、在./config/di.php文件中重新注册\PhalApi\DI()->response服务

在线调试

开启调试模式

开启调试模式很简单,主要有两种方式:

  • 单次请求开启调试:默认添加请求参数&__debug__=1
  • 全部请求开启调试:把配置文件./Config/sys.php文件中的配置改成'debug' => true,

调试信息有哪些?

正常响应的情况下,当开启调试模式后,会返回多一个debug字段,里面有相关的调试信息。如下所示:

{"ret": 200,"data": {},"msg": "","debug": {"stack": [  // 自定义埋点信息],"sqls": [  // 全部执行的SQL语句]}
}

温馨提示:调试信息仅当在开启调试模式后,才会返回并显示。

在发生未能捕捉的异常时,并且开启调试模式后,会将发生的异常转换为对应的结果按结果格式返回,即其结构会变成以下这样:

{"ret": 0,  // 异常时的错误码"data": [],"msg": "", // 异常时的错误信息"debug": {"exception": [  // 异常时的详细堆栈信息],"stack": [  // 自定义埋点信息],"sqls": [  // 全部执行的SQL语句]}
}

查看全部执行的SQL语句

debug.sqls中会显示所执行的全部SQL语句,由框架自动搜集并统计。最后显示的信息格式是:

[序号 - 当前SQL的执行时间ms]所执行的SQL语句及参数列表

示例:

[1 - 0.32ms]SELECT * FROM tbl_user WHERE (id = ?); -- 1

表示是第一条执行的SQL语句,消耗了0.32毫秒,SQL语句是SELECT * FROM tbl_user WHERE (id = ?);,其中参数是1。

自从PhalApi 2.7.0 版本后,我们对调试的SQL语句进行升级,提供了更多调试信息。新版的格式是:

[序号 - 当前SQL的执行时间ms - SQL]执行的PHP文件路径(行号):    执行的PHP类名和方法名   数据库表名    所执行的SQL语句及参数列表

例如这个例子:

[#1 - 4.03ms - SQL]/path/to/phalapi/src/app/Api/Examples/CURD.php(147):    App\\Api\\Examples\\CURD::sqlDebug()    phalapi_curd    SELECT * FROM phalapi_curd WHERE (id = 1) LIMIT 1;

从左到右,依次表示的信息是:

  • 1、在什么地方(代码位置)
  • 2、哪个类哪个方法(操作对象)
  • 3、对哪个数据库表
  • 4、进行了什么数据库操作(SQL语句和参数列表)

查看自定义埋点信息

debug.stack中埋点信息的格式如下:

[#序号 - 距离最初节点的执行时间ms - 节点标识]代码文件路径(文件行号)

示例:

[#0 - 0ms]/path/to/phalapi/public/index.php(6)

表示,这是第一个埋点(由框架自行添加),执行时间为0毫秒,所在位置是文件/path/to/phalapi/public/index.php的第6行。即第一条的埋点发生在框架初始化时。

与SQL语句的调试信息不同的是,自定义埋点则需要开发人员根据需要自行纪录,可以使用全球追踪器PhalApi\DI()->tracer进行纪录,其使用如下:

// 添加纪录埋点
PhalApi\DI()->tracer->mark();// 添加纪录埋点,并指定节点标识
PhalApi\DI()->tracer->mark('DO_SOMETHING');

通过上面方法,可以对执行经过的路径作标记。你可以指定节点标识,也可以不指定。对一些复杂的接口,可以在业务代码中添加这样的埋点,追踪接口的响应时间,以便进一步优化性能。当然,更专业的性能分析工具推荐使用XHprof。

参考:用于性能分析的XHprof扩展类库。

查看异常堆栈信息

当有未能捕捉的接口异常时,开启调试模式后,框架会把对应的异常转换成对应的返回结果,并在debug.exception中体现。而不是像正常情况直接500,页面空白。这些都是由框架自动处理的。

例如,让我们故意制造一些麻烦,手动抛出一个异常。

class Hello extends Api {public function fail() {throw new Exception('这是一个演示异常调试的示例', 501);}
}

再次请求后,除了SQL语句和自定义埋点信息外,还会看到这样的异常堆栈信息。然后便可根据返回的异常信息进行排查定位问题。

添加自定义调试信息

当需要添加其他调试信息时,可以使用PhalApi\DI()->response->setDebug()进行添加。

如:

class Hello extends Api {public function fail() {$x = 'this is x';$y = array('this is y');\PhalApi\DI()->response->setDebug('x', $x);\PhalApi\DI()->response->setDebug('y', $y);}
}

请求后,可以看到:

    "debug": {"x": "this is x","y": ["this is y"]}

推荐:协助性调试约定

PhalApi框架,可以集成众多扩展类库。当涉及多个开发者、多个开发团队,以及多个项目时,集成到PhalApi后,除了传统方式将调试信息写到日志外和直接输出到屏幕外,我们现在有了一种全新的协助性调试方式。

如前面介绍,可以添加自定义调试信息。在追加调试信息时,我们推荐约定,每个项目或扩展类库统一采用以下方式:

  • 统一使用前缀

统一使用前缀,是指在setDebug()时,对于变量名统一添加前缀,以区分不同的项目。

例如,对于XXX扩展,可以:

\PhalApi\DI()->response->setDebug('XXX_var', $var);// 其他代码……\PhalApi\DI()->response->setDebug('XXX_arr', $arr);

这样,XXX扩展就添加了两个调试变量。

同时,对于YYY扩展,可以:

\PhalApi\DI()->response->setDebug('YYY_var', $var);// 其他代码……\PhalApi\DI()->response->setDebug('YYY_arr', $arr);

这样,YYY扩展就添加了两个调试变量。

通过添加前缀,既可以明显区分不同的项目、扩展、模块和功能,又不会冲突覆盖。

1.4 PhalApi 接口响应与在线调试相关推荐

  1. WebApi接口 - 响应输出xml和json

    格式化数据这东西,主要看需要的运用场景,今天和大家分享的是webapi格式化数据,这里面的例子主要是输出json和xml的格式数据,测试用例很接近实际常用情况:希望大家喜欢,也希望各位多多扫码支持和点 ...

  2. 接口响应时组装响应json_企业实战之spring项目《接口响应体格式统一封装》

    前言 在之前的文章中我们有介绍过,如何更好.更简单的写好一个接口(接口返回值篇),今天的这篇文章我们主要介绍,怎么统一处理下接口的返回格式问题. 问题分析 我们先来分析下我们所面临的问题在哪里,然后接 ...

  3. WebApi接口 - 响应输出xml和json 转

    格式化数据这东西,主要看需要的运用场景,今天和大家分享的是webapi格式化数据,这里面的例子主要是输出json和xml的格式数据,测试用例很接近实际常用情况:希望大家喜欢,也希望各位多多扫码支持和点 ...

  4. python接口测试非json的断言_荐在接口自动化测试中,如何利用Pytest + JSONPath 进行接口响应断言...

    之前有一篇文章,介绍了如何使用JSONSchema对接口响应进行断言,主要的适用场景是对响应的数据结构进行校验,保证客户端收到的数据结构稳定和合法.今天,介绍使用JSONPath对接口响应的值进行断言 ...

  5. java接口经常变动前端怎么办_Java进程故障排查(CPU资源占用高,接口响应超时,功能接口停滞等)...

    故障分析 # 导致系统不可用情况(频率较大): 1)代码中某个位置读取数据量较大,导致系统内存耗尽,进而出现Full GC次数过多,系统缓慢: 2)代码中有比较消耗CPU的操作,导致CPU过高,系统运 ...

  6. Jmeter BeanShell采样器提取接口响应并传递(三)

    1.将fastjson-1.2.68.jar放置C:\jmeter\apache-jmeter-5.0\lib路径下 2.CSV 数据文件设置多个手机号 3.添加登录接口,${mobile}调用2种的 ...

  7. Python递归通用接口响应深层提取

    最近在做接口自动化断言时,每个接口文件里都写了一遍提取接口响应数据,然后append到列表里,传给公共的断言方法与sql查询出来的数据做比对,这样如果是100个接口,每个接口都写一遍接口响应数据提取, ...

  8. application/x-www-form-urlencoded接口响应报文中文乱码

    1.如何处理乱码 在进行接口测试时,在用httpclient post请求时,对于Content-Type:application/json来说,在写测试脚本时只需要为头信息和post请求指定相应编码 ...

  9. api 接口响应数据格式有哪些

    api接口响应数据格式有: 1.基本格式 2.对象格式 3.数组格式 4.分页格式 基本格式返回的数据 { "code":200, "msg":"登录 ...

最新文章

  1. 如何自动将AI Studio中的GIF文件上载到CSDN?
  2. Python学习之解决python下载第三方依赖速度慢的问题
  3. Python类中的self到底是干啥的
  4. python 如何取负数?直接加负号( - )
  5. 表达式求值负数乘负数_为什么现在很多期权的时间价值都为负数?
  6. mysql 出现 quot_MYSQL 新版出现 Client does_mysql _ 搞代码
  7. 全球首个!腾讯优图开源3D医疗影像大数据预训练模型
  8. CentOS 7上安装 MongoDB数据库 4.0.0最新版
  9. 取磁碟名稱 c++_安徽CDCSCONT PLUS/R/C/E生产厂家,联锁板生产厂家
  10. Oracle数据库异常---OracleDBConsoleorcl无法启动
  11. 怎么删除计算机的一个用户名和密码,哪位晓得电脑有两个账户怎么删除一个
  12. Sublime Text3的插件管理Package Control安装
  13. System.IO.Path 操作
  14. 高通平台SPI驱动框架分析
  15. 【ICCV2019论文阅读】PU-GAN:点云上采样对抗网络
  16. 北京地铁21号线_北京迎来地铁22号线,全长81公里,沿线的市民有福了
  17. win10商店下载主题壁纸提取
  18. win激活时错误0xc0000022
  19. sudo 切换用户 普通用户
  20. 1367 二叉树中的列表(递归)

热门文章

  1. IntelliJ IDEA 自动导入包 快捷方式
  2. 前端form表单提交的方式
  3. 卷积神经网络技术及发展
  4. 英语听力突破掌上宝Reading
  5. JavaScript-面向对象精讲系列-李游Leo-专题视频课程
  6. 《塞尔达:时之笛》感想:空筐的艺术
  7. 本科段计算机应用基础和实践,自考计算机应用基础难吗 要考哪些内容
  8. 电竞手机全面进化后什么样?红魔8 Pro告诉你
  9. 想让云端平台内存占用变小的方法参考
  10. 是phalcon快还是java快_PHP 框架:Yaf 和 Phalcon 谁更快?