基于 Yii 2 的 HTTP 客户端扩展的响应处理的现阶段时间内的最佳实践(在之前的实现上有所优化,在后续一段时间内皆如此实践,HTTP 客户端组件的本地化,返回的处理逻辑的简化等)
1、获取菜单列表,如图1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | { "code": 10000, "message": "获取菜单列表成功", "data": { "items": [ { "id": "974b2b64aac24973dbd39b40fb2cc880", "item_title": "文章审核", "item_link": "", "item_desc": "", "item_type": "category", "item_sort": "1", "item_pid": "0", "item_target": "0", "is_iframe": "1", "children": [] }, { "id": "61600e1530e7671346fe6e436195f4b7", "item_title": "平台管控", "item_link": "", "item_desc": "", "item_type": "category", "item_sort": "2", "item_pid": "0", "item_target": "0", "is_iframe": "1", "children": [] }, { "id": "66c8e5ce3261710ccc90841141939c92", "item_title": "设置", "item_link": "", "item_desc": "", "item_type": "category", "item_sort": "3", "item_pid": "0", "item_target": "0", "is_iframe": "1", "children": [] } ], "_links": { "self": { } }, "_meta": { "totalCount": 3, "pageCount": 1, "currentPage": 1, "perPage": 20 } } } |
2、查看 Available Debug Data,其数据来源于 HTTP,如图2
1 2 | Cookie: login_chinamcloud_id=2e368664c41b8bf511bcc9c65d86dbc3; login_chinamcloud_tid=0c4dba79f6028dcfc519917a45b98bba |
3、查看 HTTP 模型文件:common/logics/http/cmc_console/Menu.php,代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | <?php /** * Created by PhpStorm. * User: Qiang Wang * Date: 2018/02/28 * Time: 13:14 */ namespace common\logics\http\cmc_console; use Yii; use yii\web\HttpException; use yii\web\ServerErrorHttpException; /** * 框架服务控制台的菜单 * * @author Qiang Wang <shuijingwanwq@163.com> * @since 1.0 */ class Menu extends Model { public $service_key ; public $login_id ; public $login_tid ; public function rules() { return [ // login_id、login_tid 属性必须有值 [[ 'login_id' , 'login_tid' ], 'required' ], ]; } public function attributeLabels() { return [ 'service_key' => \Yii::t( 'model/http/cmc-console/menu' , 'Service Key' ), 'login_id' => \Yii::t( 'model/http/cmc-console/menu' , 'Login Id' ), 'login_tid' => \Yii::t( 'model/http/cmc-console/menu' , 'Login Tid' ), ]; } /** * 返回模块的菜单信息 * * @param string $loginId 用户标识 * @param string $loginTid 登录标识 * * @return array|bool * * 格式如下: * * 框架服务控制台的菜单信息 * [ * 'message' => '', //说明 * 'data' => [], //数据 * ] * * 失败(将错误保存在 [[yii\base\Model::errors]] 属性中) * false * * @throws ServerErrorHttpException 如果响应状态码不等于20x * @throws HttpException 如果登录超时 */ public function getMenu( $loginId , $loginTid ) { $this ->service_key = Yii:: $app ->params[ 'cmcConsole' ][ 'serviceKey' ]; $this ->login_id = $loginId ; $this ->login_tid = $loginTid ; $cookie = 'login_chinamcloud_id=' . $this ->login_id . '; login_chinamcloud_tid=' . $this ->login_tid . '' ; $response = Yii:: $app ->cmcConsoleHttp->createRequest() ->setHeaders([ 'Cookie' => $cookie ]) ->setMethod( 'get' ) ->setUrl( 'nav-bar/service-side-bar' ) ->setData([ 'service_key' => $this ->service_key, ]) ->send(); // 检查响应状态码是否等于20x if ( $response ->isOk) { // 检查业务逻辑是否成功 if ( $response ->data[ 'code' ] === 10000) { $cmcConsoleData = [ 'message' => $response ->data[ 'message' ], 'data' => $response ->data[ 'data' ][ 'menu_data' ]]; return $cmcConsoleData ; } elseif ( $response ->data[ 'code' ] === 99998) { // 登录超时 throw new HttpException(302, Yii::t( 'error' , Yii::t( 'error' , Yii::t( 'error' , '201003' ), [ 'message' => $response ->data[ 'message' ]])), 201003); } else { $this ->addError( 'service_key' , $response ->data[ 'message' ]); return false; } } else { throw new ServerErrorHttpException(Yii::t( 'error' , Yii::t( 'error' , Yii::t( 'error' , '201001' ), [ 'status_code' => $response ->statusCode])), 201001); } } } |
4、cmcConsoleHttp 是一个组件,通过应用组件配置 HTTP 客户端,参考网址:https://www.yiiframework.com/extension/yiisoft/yii2-httpclient/doc/guide/2.0/zh-cn/usage-setup-client-instance ,查看配置文件:common/config/main-local.php
1 2 3 4 5 | 'cmcConsoleHttp' => [ 'class' => 'yii\httpclient\Client' , 'transport' => 'yii\httpclient\CurlTransport' ], |
5、查看参数文件:common/config/params-local.php,存在与 HTTP 客户端相关的配置参数
1 2 3 4 5 6 7 8 | // 框架服务控制台 'cmcConsole' => [ 'baseUrl' => '' , // BASE URL 'appKey' => 'assZdqfgOXcIFDvG' , // 模块Key 'appSecret' => 'sd3fe4GDSRqrl7mLFyP7ogbk1pDFwzT' , // 模块Secret 'serviceKey' => 'cmcp' , // 服务标识 ], |
6、查看方法文件:api/rests/menu/IndexAction.php,调用 HTTP 模型的方法:getMenu,代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | // 所有输入数据都有效,获取模块的菜单信息 $menu = $model ->getMenu( $model ->login_id, $model ->login_tid); if ( $menu === false) { if ( $model ->hasErrors()) { $firstError = '' ; foreach ( $model ->getFirstErrors() as $message ) { $firstError = $message ; break ; } throw new ServerErrorHttpException(Yii::t( 'error' , Yii::t( 'error' , Yii::t( 'error' , '226020' ), [ 'first_error' => $firstError ])), 226020); } elseif (! $model ->hasErrors()) { throw new ServerErrorHttpException( 'Authority Center HTTP requests fail for unknown reasons.' ); } } |
7、现阶段的实现,存在 4 个问题,如图3
(1)当应用中需要基于 HTTP 调用多个服务时,应用组件的数量会持续地增加,请谨慎注册太多应用组件,应用组件就像全局变量,使用太多可能加大测试和维护的难度。一般情况下可以在需要时再创建本地组件。
(2)新增加一个 HTTP 组件时,需要同时在配置文件:common/config/main-local.php、common/config/params-local.php,有所重复,冗余了些。
(3)当响应状态码不等于20x时,认为调用失败(绝大部份情况下,此业务逻辑成立)。抛出服务器错误异常,此时,错误异常信息不够完善,一旦调用失败,很难排查具体错误原因。
(4)调用 HTTP 模型的方法时,对于返回的处理逻辑,过于复杂,显得冗余了些,需要有所精简。
8、先解决第 1 个问题,参考网址:https://www.yiiframework.com/extension/yiisoft/yii2-httpclient/doc/guide/2.0/zh-cn/usage-setup-client-instance ,将 yii\httpclient\Client 实例封装为本地组件
9、查看继承关系:yii\httpclient\Client » yii\base\Component,common\logics\http\cmc_console\Menu » common\logics\http\cmc_console\Model » \yii\base\Model » yii\base\Component,因此,可在模型:common\logics\http\cmc_console\Model 中将 yii\httpclient\Client 实例封装为本地组件,编辑 common/logics/http/cmc_console/Model.php,创建 HTTP 客户端对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | <?php /** * Created by PhpStorm. * User: Qiang Wang * Date: 2018/02/28 * Time: 13:14 */ namespace common\logics\http\cmc_console; use Yii; use yii\base\InvalidConfigException; use yii\httpclient\Client; use yii\httpclient\CurlTransport; /** * 框架服务控制台的基础类 * * @author Qiang Wang <shuijingwanwq@163.com> * @since 1.0 */ class Model extends \yii\base\Model { private $_httpClient ; /* * 创建 HTTP 客户端对象 * * @return object the created object * @throws InvalidConfigException if a registered parser does not implement the [[RequestParserInterface]]. */ public function getHttpClient() { if (! is_object ( $this ->_httpClient)) { $this ->_httpClient = Yii::createObject([ 'class' => Client::className(), 'baseUrl' => Yii:: $app ->params[ 'cmcConsole' ][ 'hostInfo' ] . Yii:: $app ->params[ 'cmcConsole' ][ 'baseUrl' ], 'transport' => CurlTransport::className(), ]); } return $this ->_httpClient; } } |
10、编辑 HTTP 模型文件:common/logics/http/cmc_console/Menu.php,Yii::$app->cmcConsoleHttp 替换为 $this->httpClient
1 2 3 4 5 6 7 8 | $response = $this ->httpClient->createRequest() ->setHeaders([ 'Cookie' => $cookie ]) ->setMethod( 'get' ) ->setUrl( 'nav-bar/service-side-bar' ) ->setData([ 'service_key' => $this ->service_key, ]) ->send(); |
11、编辑配置文件:common/config/main-local.php,删除组件:cmcConsoleHttp
12、获取菜单列表,仍然是可正常获取,查看 Available Debug Data,其数据来源于 HTTP,请求无变化,如图4
13、此时,前 2 个问题皆已经得到解决,先解决第 3 个问题,调用 HTTP 模型的方法时,对于返回的处理逻辑,过于复杂,显得冗余了些,需要有所精简。编辑 HTTP 模型文件:common/logics/http/cmc_console/Menu.php,当响应状态码等于 500 时,即不等于20x时,认为调用失败(绝大部份情况下,此业务逻辑成立)。打印响应对象
1 2 3 4 5 6 7 8 9 10 | $response = $this ->httpClient->createRequest() ->setHeaders([ 'Cookie' => $cookie ]) ->setMethod( 'get' ) ->setUrl( 'nav-bar/service-side-bar-1' ) ->setData([ 'service_key' => $this ->service_key, ]) ->send(); print_r( $response ); exit ; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | yii\httpclient\Response Object ( [client] => yii\httpclient\Client Object ( [baseUrl] => https://cmcconsole.flydev.chinamcloud.cn [formatters] => Array ( [urlencoded] => yii\httpclient\UrlEncodedFormatter Object ( [encodingType] => 1 [charset] => ) ) [parsers] => Array ( ) [requestConfig] => Array ( ) [responseConfig] => Array ( ) [contentLoggingMaxSize] => 2000 [_transport:yii\httpclient\Client:private] => yii\httpclient\CurlTransport Object ( [_events:yii\base\Component:private] => Array ( ) [_eventWildcards:yii\base\Component:private] => Array ( ) [_behaviors:yii\base\Component:private] => ) [_events:yii\base\Component:private] => Array ( ) [_eventWildcards:yii\base\Component:private] => Array ( ) [_behaviors:yii\base\Component:private] => Array ( ) ) [_headers:yii\httpclient\Message:private] => Array ( [0] => HTTP/1.1 500 Internal Server Error [1] => Server: nginx [2] => Date: Wed, 11 Dec 2019 05:59:37 GMT [3] => Content-Type: text/html; charset=UTF-8 [4] => Transfer-Encoding: chunked [5] => Connection: keep-alive [6] => Access-Control-Allow-Origin: [7] => Access-Control-Allow-Methods: * [8] => Access-Control-Allow-Credentials: true [9] => Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization ) [_cookies:yii\httpclient\Message:private] => [_content:yii\httpclient\Message:private] => <pre>An Error occurred while handling another error: yii\base\InvalidRouteException: Unable to resolve the request "site/error". in /home/www/cmc_console/vendor/yiisoft/yii2/base/Module.php:537 Stack trace: #0 /home/www/cmc_console/vendor/yiisoft/yii2/web/ErrorHandler.php(97): yii\base\Module->runAction('site/error') #1 /home/www/cmc_console/vendor/yiisoft/yii2/base/ErrorHandler.php(111): yii\web\ErrorHandler->renderException(Object(yii\web\NotFoundHttpException)) #2 /home/www/cmc_console/vendor/sentry/Raven/ErrorHandler.php(86): yii\base\ErrorHandler->handleException(Object(yii\web\NotFoundHttpException)) #3 [internal function]: Raven_ErrorHandler->handleException(Object(yii\web\NotFoundHttpException)) #4 {main} Previous exception: yii\base\InvalidRouteException: Unable to resolve the request: nav-bar/service-side-bar-1 in /home/www/cmc_console/vendor/yiisoft/yii2/base/Controller.php:143 Stack trace: #0 /home/www/cmc_console/vendor/yiisoft/yii2/base/Module.php(528): yii\base\Controller->runAction('service-side-ba...', Array) #1 /home/www/cmc_console/vendor/yiisoft/yii2/web/Application.php(103): yii\base\Module->runAction('nav-bar/service...', Array) #2 /home/www/cmc_console/vendor/yiisoft/yii2/base/Application.php(386): yii\web\Application->handleRequest(Object(yii\web\Request)) #3 /home/www/cmc_console/web/index.php(13): yii\base\Application->run() #4 {main} Next yii\web\NotFoundHttpException: 页面未找到。 in /home/www/cmc_console/vendor/yiisoft/yii2/web/Application.php:115 Stack trace: #0 /home/www/cmc_console/vendor/yiisoft/yii2/base/Application.php(386): yii\web\Application->handleRequest(Object(yii\web\Request)) #1 /home/www/cmc_console/web/index.php(13): yii\base\Application->run() #2 {main}</pre> [_data:yii\httpclient\Message:private] => [_format:yii\httpclient\Message:private] => [_events:yii\base\Component:private] => Array ( ) [_eventWildcards:yii\base\Component:private] => Array ( ) [_behaviors:yii\base\Component:private] => ) |
14、编辑 HTTP 模型文件:common/logics/http/cmc_console/Menu.php,当响应状态码等于 500 时,即不等于20x时,认为调用失败(绝大部份情况下,此业务逻辑成立)。打印响应数据
1 2 3 4 5 6 7 8 9 10 | $response = $this ->httpClient->createRequest() ->setHeaders([ 'Cookie' => $cookie ]) ->setMethod( 'get' ) ->setUrl( 'nav-bar/service-side-bar-1' ) ->setData([ 'service_key' => $this ->service_key, ]) ->send(); print_r( $response ->data); exit ; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | Array ( [0] => An Error occurred while handling another error: yii\base\InvalidRouteException: Unable to resolve the request "site/error". in /home/www/cmc_console/vendor/yiisoft/yii2/base/Module.php:537 Stack trace: #0 /home/www/cmc_console/vendor/yiisoft/yii2/web/ErrorHandler.php(97): yii\base\Module->runAction('site/error') #1 /home/www/cmc_console/vendor/yiisoft/yii2/base/ErrorHandler.php(111): yii\web\ErrorHandler->renderException(Object(yii\web\NotFoundHttpException)) #2 /home/www/cmc_console/vendor/sentry/Raven/ErrorHandler.php(86): yii\base\ErrorHandler->handleException(Object(yii\web\NotFoundHttpException)) #3 [internal function]: Raven_ErrorHandler->handleException(Object(yii\web\NotFoundHttpException)) #4 {main} Previous exception: yii\base\InvalidRouteException: Unable to resolve the request: nav-bar/service-side-bar-1 in /home/www/cmc_console/vendor/yiisoft/yii2/base/Controller.php:143 Stack trace: #0 /home/www/cmc_console/vendor/yiisoft/yii2/base/Module.php(528): yii\base\Controller->runAction('service-side-ba...', Array) #1 /home/www/cmc_console/vendor/yiisoft/yii2/web/Application.php(103): yii\base\Module->runAction('nav-bar/service...', Array) #2 /home/www/cmc_console/vendor/yiisoft/yii2/base/Application.php(386): yii\web\Application->handleRequest(Object(yii\web\Request)) #3 /home/www/cmc_console/web/index.php(13): yii\base\Application->run() #4 {main} Next yii\web\NotFoundHttpException: 页面未找到。 in /home/www/cmc_console/vendor/yiisoft/yii2/web/Application.php:115 Stack trace: #0 /home/www/cmc_console/vendor/yiisoft/yii2/base/Application.php(386): yii\web\Application->handleRequest(Object(yii\web\Request)) #1 /home/www/cmc_console/web/index.php(13): yii\base\Application->run() #2 {main} ) |
15、编辑 HTTP 模型文件:common/logics/http/cmc_console/Menu.php,当响应状态码等于 500 时,即不等于20x时,认为调用失败(绝大部份情况下,此业务逻辑成立)。抛出服务器错误异常,此时,错误异常信息不够完善,一旦调用失败,很难排查具体错误原因
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | $response = $this ->httpClient->createRequest() ->setHeaders([ 'Cookie' => $cookie ]) ->setMethod( 'get' ) ->setUrl( 'nav-bar/service-side-bar-1' ) ->setData([ 'service_key' => $this ->service_key, ]) ->send(); // 检查响应状态码是否等于20x if ( $response ->isOk) { // 检查业务逻辑是否成功 if ( $response ->data[ 'code' ] === 10000) { $cmcConsoleData = [ 'message' => $response ->data[ 'message' ], 'data' => $response ->data[ 'data' ][ 'menu_data' ]]; return $cmcConsoleData ; } elseif ( $response ->data[ 'code' ] === 99998) { // 登录超时 throw new HttpException(302, Yii::t( 'error' , Yii::t( 'error' , Yii::t( 'error' , '201003' ), [ 'message' => $response ->data[ 'message' ]])), 201003); } else { $this ->addError( 'service_key' , $response ->data[ 'message' ]); return false; } } else { throw new ServerErrorHttpException(Yii::t( 'error' , Yii::t( 'error' , Yii::t( 'error' , '201001' ), [ 'status_code' => $response ->statusCode])), 201001); } |
1 2 3 4 5 6 7 | { "name": "Internal Server Error", "message": "框架服务控制台HTTP请求失败,状态码:500", "code": 201001, "status": 500, "type": "yii\\web\\ServerErrorHttpException" } |
16、编辑 HTTP 模型文件:common/logics/http/cmc_console/Menu.php,当响应状态码等于 500 时,即不等于20x时,认为调用失败(绝大部份情况下,此业务逻辑成立)。抛出服务器错误异常,完善错误异常信息,一旦调用失败,可以更为容易地排查具体错误原因,如图5
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | $response = $this ->httpClient->createRequest() ->setHeaders([ 'Cookie' => $cookie ]) ->setMethod( 'get' ) ->setUrl( 'nav-bar/service-side-bar-1' ) ->setData([ 'service_key' => $this ->service_key, ]) ->send(); // 检查响应状态码是否等于20x if ( $response ->isOk) { // 检查业务逻辑是否成功 if ( $response ->data[ 'code' ] === 10000) { $cmcConsoleData = [ 'message' => $response ->data[ 'message' ], 'data' => $response ->data[ 'data' ][ 'menu_data' ]]; return $cmcConsoleData ; } elseif ( $response ->data[ 'code' ] === 99998) { // 登录超时 throw new HttpException(302, Yii::t( 'error' , Yii::t( 'error' , Yii::t( 'error' , '201003' ), [ 'message' => $response ->data[ 'message' ]])), 201003); } else { $this ->addError( 'service_key' , $response ->data[ 'message' ]); return false; } } else { $code = isset( $response ->data[ 'code' ]) ? $response ->data[ 'code' ] : 0; // 返回码 $message = isset( $response ->data[0]) ? $response ->data[0] : '' ; // 说明 throw new ServerErrorHttpException(Yii::t( 'error' , Yii::t( 'error' , Yii::t( 'error' , '201001' ), [ 'status_code' => $response ->statusCode, 'code' => $code , 'message' => $message ])), 201001); } |
1 2 3 4 5 6 7 | { "name": "Internal Server Error", "message": "框架服务控制台HTTP请求失败,状态码:500,返回码:0,说明:An Error occurred while handling another error:\nyii\\base\\InvalidRouteException: Unable to resolve the request \"site/error\". in /home/www/cmc_console/vendor/yiisoft/yii2/base/Module.php:537\nStack trace:\n#0 /home/www/cmc_console/vendor/yiisoft/yii2/web/ErrorHandler.php(97): yii\\base\\Module->runAction('site/error')\n#1 /home/www/cmc_console/vendor/yiisoft/yii2/base/ErrorHandler.php(111): yii\\web\\ErrorHandler->renderException(Object(yii\\web\\NotFoundHttpException))\n#2 /home/www/cmc_console/vendor/sentry/Raven/ErrorHandler.php(86): yii\\base\\ErrorHandler->handleException(Object(yii\\web\\NotFoundHttpException))\n#3 [internal function]: Raven_ErrorHandler->handleException(Object(yii\\web\\NotFoundHttpException))\n#4 {main}\nPrevious exception:\nyii\\base\\InvalidRouteException: Unable to resolve the request: nav-bar/service-side-bar-1 in /home/www/cmc_console/vendor/yiisoft/yii2/base/Controller.php:143\nStack trace:\n#0 /home/www/cmc_console/vendor/yiisoft/yii2/base/Module.php(528): yii\\base\\Controller->runAction('service-side-ba...', Array)\n#1 /home/www/cmc_console/vendor/yiisoft/yii2/web/Application.php(103): yii\\base\\Module->runAction('nav-bar/service...', Array)\n#2 /home/www/cmc_console/vendor/yiisoft/yii2/base/Application.php(386): yii\\web\\Application->handleRequest(Object(yii\\web\\Request))\n#3 /home/www/cmc_console/web/index.php(13): yii\\base\\Application->run()\n#4 {main}\n\nNext yii\\web\\NotFoundHttpException: 页面未找到。 in /home/www/cmc_console/vendor/yiisoft/yii2/web/Application.php:115\nStack trace:\n#0 /home/www/cmc_console/vendor/yiisoft/yii2/base/Application.php(386): yii\\web\\Application->handleRequest(Object(yii\\web\\Request))\n#1 /home/www/cmc_console/web/index.php(13): yii\\base\\Application->run()\n#2 {main}", "code": 201001, "status": 500, "type": "yii\\web\\ServerErrorHttpException" } |
17、此时,前 3 个问题皆已经得到解决,仅剩下第 4 个问题,编辑 HTTP 模型文件:common/logics/http/cmc_console/Menu.php,参考 yii\base\Model::validate(),当响应状态码等于20x,但返回码不等于约定的成功返回码时,即业务逻辑失败,在将错误保存在 yii\base\Model::$errors 属性中后,不直接返回 false,而是返回 !$this->hasErrors()。在这种情况下,为何不也抛出异常,目的在于让调用方可以更为灵活地处理此种情况,是否抛出异常由调用方决定,而不是模型方法本身。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | $response = $this ->httpClient->createRequest() ->setHeaders([ 'Cookie' => $cookie ]) ->setMethod( 'get' ) ->setUrl( 'nav-bar/service-side-bar' ) ->setData([ 'service_key' => $this ->service_key, ]) ->send(); // 检查响应状态码是否等于20x $responseCode = isset( $response ->data[ 'code' ]) ? $response ->data[ 'code' ] : 0; // 返回码 $responseMessage = isset( $response ->data[0]) ? $response ->data[0] : '' ; // 说明 if ( $response ->isOk) { // 检查业务逻辑是否成功 if ( $responseCode === 10000) { return [ 'message' => $response ->data[ 'message' ], 'data' => $response ->data[ 'data' ][ 'menu_data' ]]; } elseif ( $responseCode === 99998) { // 登录超时 throw new HttpException(302, Yii::t( 'error' , Yii::t( 'error' , Yii::t( 'error' , '201002' ), [ 'code' => $responseCode , 'message' => $response ->data[ 'message' ]])), 201003); } else { $this ->addError( 'id' , Yii::t( 'error' , Yii::t( 'error' , Yii::t( 'error' , '201002' ), [ 'code' => $responseCode , 'message' => $response ->data[ 'message' ]]))); return ! $this ->hasErrors(); } } else { throw new ServerErrorHttpException(Yii::t( 'error' , Yii::t( 'error' , Yii::t( 'error' , '201001' ), [ 'status_code' => $response ->statusCode, 'code' => $responseCode , 'message' => $responseMessage ])), 201001); } |
18、语言文件有所调整
common/messages/zh-CN/error.php
1 2 3 4 | 201001 => '框架服务控制台HTTP请求失败,状态码:{status_code},返回码:{code},说明:{message}' , 201002 => '框架服务控制台HTTP请求失败,返回码:{code},说明:{message}' , 201003 => '' , 201010 => '{first_error}' , |
api/messages/zh-CN/error.php
1 | 226020 => '{first_error}' , |
19、编辑方法文件:api/rests/menu/IndexAction.php,调用 HTTP 模型的方法:getMenu,由于 HTTP 模型文件 不直接返回 false,而是返回 !$this->hasErrors(),那么当返回 false 时,$model->hasErrors() 肯定等于 true,因此,可以省略其判断,代码如下
1 2 3 4 5 6 7 8 9 10 11 | // 所有输入数据都有效,获取模块的菜单信息 $menu = $model ->getMenu( $model ->login_id, $model ->login_tid); if (! $menu ) { $firstError = '' ; foreach ( $model ->getFirstErrors() as $message ) { $firstError = $message ; break ; } throw new ServerErrorHttpException(Yii::t( 'error' , Yii::t( 'error' , Yii::t( 'error' , '226020' ), [ 'first_error' => $firstError ])), 226020); } |
20、当响应状态码等于20x,但返回码不等于约定的成功返回码时,即业务逻辑失败,获取菜单列表,符合预期,最后一个问题得到解决,如图6
1 2 3 4 5 6 7 | { "name": "Internal Server Error", "message": "框架服务控制台HTTP请求失败,返回码:99999,说明:menu_id不能为空", "code": 226020, "status": 500, "type": "yii\\web\\ServerErrorHttpException" } |
21、由于模型目录:common/logics/http/cmc_console 中的所有模型文件,皆是基于同一 HTTP 客户端组件,因此,其响应的处理逻辑基本上是一致的。决定将响应的处理逻辑封装为一个公共的方法,以便于复用。编辑 common/logics/http/cmc_console/Model.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | /* * 响应对象的处理 * * @param object $response 响应对象 * * @return array|bool * * 格式如下: * * 框架服务控制台的菜单信息 * [ * 'message' => '', //说明 * 'data' => [], //数据 * ] * * 失败(将错误保存在 [[yii\base\Model::errors]] 属性中) * false * * @throws ServerErrorHttpException 如果响应状态码不等于20x * @throws HttpException 如果登录超时 */ public function responseHandler( $response ) { // 检查响应状态码是否等于20x $responseCode = isset( $response ->data[ 'code' ]) ? $response ->data[ 'code' ] : 0; // 返回码 if ( $response ->isOk) { // 检查业务逻辑是否成功 if ( $responseCode === 10000) { return [ 'message' => $response ->data[ 'message' ], 'data' => $response ->data[ 'data' ]]; } elseif ( $responseCode === 99998) { // 登录超时 throw new HttpException(302, Yii::t( 'error' , Yii::t( 'error' , Yii::t( 'error' , '201002' ), [ 'code' => $responseCode , 'message' => $response ->data[ 'message' ]])), 201003); } else { $this ->addError( 'id' , Yii::t( 'error' , Yii::t( 'error' , Yii::t( 'error' , '201002' ), [ 'code' => $responseCode , 'message' => $response ->data[ 'message' ]]))); return ! $this ->hasErrors(); } } else { $responseMessage = isset( $response ->data[0]) ? $response ->data[0] : '' ; // 说明 throw new ServerErrorHttpException(Yii::t( 'error' , Yii::t( 'error' , Yii::t( 'error' , '201001' ), [ 'status_code' => $response ->statusCode, 'code' => $responseCode , 'message' => $responseMessage ])), 201001); } } |
22、编辑 HTTP 模型文件:common/logics/http/cmc_console/Menu.php,在方法:getMenu 中,调用公共的响应对象的处理方法:responseHandler($response)
1 2 3 4 5 6 7 8 9 | $response = $this ->httpClient->createRequest() ->setHeaders([ 'Cookie' => $cookie ]) ->setMethod( 'get' ) ->setUrl( 'nav-bar/service-side-bar' ) ->setData([ 'service_key' => $this ->service_key, ]) ->send(); return $this ->responseHandler( $response ); |
近期评论