备注:总结中可能还有诸多不完善的地方,后续还会持续完善

下面的开发规范是在做了多个项目后总结提炼的一个接口框架,专门适用于API接口开发的场景,主要考美观、日志定位方便、可读性好等特点。这里接口的调用统一采用POST方法。

备注:这里选择CI框架而不选择目使用最多的Laravel框架,主要考虑两点:

  • CI框架性能优于Laravel
  • CI框架比较轻,而Laravel框架比较重型,比较适合于后台管理系统的开发场景

标准输入

{
    "Action": "DemoAction",
    "Version": "2019-01-01",
    "Language": "zh",
    "RequestId": "6ef60bec-0242-43af-bb20-270359fb54a7",

    "Field1": "",
    "Field2": "",
    "Fieldn": "",

}

说明:
(1)Action:接口名,每一个接口名对应框架中的一个PHP控制器类文件
(2)Version:版本号
(3)Language:支持多国语言(这里也可以在请求头中的Accept-Language设置)
(4)RequestId:输入和输出中RequestId都是唯一的并且相等,这个方便后期出现问题时能快速排查定位(备注:这里RequestId是由服务器唯一生成,不是由客户端生成)
(5)其他字段:请求的输入数据

标准输出

{
    "Response":{
        "Action":"DemoAction",
        "Data":[

        ],
        "RequestId":"6ef60bec-0242-43af-bb20-270359fb54a7",
        "RetCode":0,
        "RetMsg":"Success"
    }
}

说明:
(1)Action:接口名,每一个接口名对应框架中的一个PHP控制器类
(2)Data:返回的数据保存在该字段
(3)RequestId:输入和输出中RequestId都是唯一的并且相等,这个方便后期出现问题时能快速排查定位
(4)RetCode:返回码,0表示成功,非0表示失败,具体映射可扩展
(5)RetMsg:返回消息

接口设计逻辑

每一个接口对应一个控制器,也就是一个接口对应一个类文件。每一个接口文件都继承MY_Controller,子类中主要实现两个逻辑,一个是verifyInput方法,对输入进行校验,另一个是todo方法,接口的业务逻辑在这里实现。当然跟数据库操作相关的逻辑要在model层实现。这样就可以让代码逻辑变得很清晰。

控制器设计
<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class MY_Controller extends CI_Controller {

    protected $_resp = [
        'Response' => []
    ];

    public function __construct(){
        parent::__construct();

    }
    
    /**
     * 将结果输出
     * @param $errorCode
     * @param $errorMsg
     */
    protected function response($errorCode=null, $errorMsg=null)
    {
        if ($errorCode) {
            $this->_resp['Response']['RetCode'] = $errorCode;
            $this->_resp['Response']['RetMsg'] = $errorMsg;
        } else {
            $this->_resp['Response']['RetCode'] = 0;
            $this->_resp['Response']['RetMsg'] = "Success";
        }

        log_message('info', json_encode($this->_resp));
        header('Content-Type:application/json; charset=utf-8');
        echo json_encode($this->_resp) . "\n";
    }
    
    /**
     * 参数初始化
     * @param $params
     * @return bool
     */
    protected function initParams(&$params)
    {
        $params = rawurldecode($params);
        $params = json_decode($params, true );

        $this->_resp['Response']['RequestId'] = $params['RequestId'];
        if( !$this->verifyInput($params) ){
            return false;
        }
    return true;
    }
    
    
    /**
     * 校验参数合法性
     * @param $params
     * @return bool
     */
    protected function verifyInput( $params )
    {
        //todo
        return true;
    }

    /**
     * 主逻辑
     * @param $params
     * @return bool
     */
    protected function todo($params)
    {
        //todo
    }
    

}

下面看一下具体实现一个接口的示例:

<?php
defined('BASEPATH') OR exit('No direct script access allowed');

/**
 * 【xxx接口】
 * 每一个接口对应一个Controller
 */
class DemoAction extends MY_Controller
{

    public function __construct()
    {
        parent::__construct();

        $this->_resp['Response']['Action'] = 'DemoAction';
        $this->_resp['Response']['Data'] = [];
    }

    /**
     * 校验参数合法性
     * @param $params
     * @return bool
     */
    protected function verifyInput($params)
    {
        if (parent::verifyInput($params) == false) {
            return false;
        }

        //todo

        return true;
    }

    /**
     * 主逻辑
     * @param $params
     * @return bool
     */
    public function todo($params)
    {
        if (!$this->initParams($params)) {
            $this->response(ErrorCode::ParamErrorCode, ErrorCode::ParamErrorMsg);
            return;
        }

        //todo

        $this->response();
    }

}

错误码设计

设计API接口,错误码提示很重要,开发者,可以在application/core/ErrorCode.php中设计映射关系,并可以在所有文件中使用。

错误码映射文件设计
<?php

class ErrorCode
{
    //ErrorCode和ErrorMsg一一映射
    const ParamErrorCode = 1001;
    const ParamErrorMsg = "Parameter Error";

    const DbErrorCode = 2001;
    const DbErrorMsg = "Database Error";

    //todo

}

完整的框架代码我已经上传到github上:api_framework

打赏

发表评论

电子邮件地址不会被公开。