lumen_rule_controller.md 6.38 KB

LUMEN+API Controller 规范

1. 第三方依赖库规范

在使用LUMEN实现API接口时,以下库必须需要包含在composer包依赖中,以实现代码编写的一些规范

  • dingo/api : 实现API接口库
  • vlucas/phpdotenv : 实现了配置文件读取的函数,包括env()函数等
  • marc-mabe/php-enum : 实现php的ENUM功能
  • barryvdh/laravel-ide-helper : IDE帮助,_ide_helper.php文件提供

2. Controller规范

  • 所有Controller的基类以编写定义的BasicController为准。BasicController实现了一些基本的HTTP请求和应答功能。如$requestHander变量处理请求,respond函数处理应答。Trait类UtilToolMethod实现了通用功能函数。

  • 所有的Controller不再使用Request对象,而使用BasicController中的$requestHandler变量。

  • $requestHandler变量使用不再推荐使用数组形式结构获得参数变量,而使用使用其暴露的方法

  $this->requestHandler->input('key1','');
  $this->requestHandler->all();
  $this->requestHandler->only(['key1','key2']);
  $this->requestHandler->file('file');
  $this->requestHandler->header('Authorization');
  $this->requestHandler->url();
  $this->requestHandler->path();
  • 对于请求参数的验证,统一使用validate方法
  $this->validate($this->requestHandler,[
        'key1'  => 'required'
  ]);
  • 对于自己业务有特殊需求的,在BasicController基础上,扩展Controller的功能和方法。 然后再让其它的Controller类继承这个定义的Controller
  /**
   * 应用授权用户基类,提供用户数据及用户操作方法
   */
  class UserAuthBasicControll extends BaiscController
  {
      /**
       * @var GuiderEmpUser
       */
      private $_empUser = null;

    public function __construct(Request $request,GuiderEmpUser $guiderEmpUser) {
            parent::__construct($reuqest);
          $this->_empUser = $guiderEmpUser;
    }

      /**
       * @return GuiderEmpUser
       */
      public function getEmpUser() { return $this->_empUser; }

      public function userSiteAccess($pointSiteId) { /* 实现权限验证.. */ }
  }
  • Controller层函数使用对象的自动注入依赖。
  class CustomerController 
  {

      private $_crmService = null;

      public function __construct(CRMService $crmService) {
         $this->_crmService = $crmService;  // 自动注入依赖
      }

      public function customerEnterIn($userInfo) {
         $this->_crmService->registerCustomer($userInfo);
      }
  }
  • Controller层不能直接操作SQL,不能直接操作Model对象实现SQL功能。要实现数据库增删改,必须通过Model封装起来。以下方法在Controller中直接操作DB表都是被禁止的
  class SomeController 
  {
      public function doSomeErrorThing() {
          DB::table('t1')->insert([...]);
          UserModel::where('user'=>'my')->update([...]);
          DB::table('users')->truncate();
      }

      /* 对于查询来说,简单的查询可以在Controller直接完成,复杂的查询需要通过Model层添加方法来完成 */
      public function userOperator() {
          $id = 100;
          $userInstance1    = User::find($id);
          $userInstance2    = (new User())->getUserInstanceById($id);
          $userAccesseList  = (new User())->getUserAccesses($id);
      }
  }
  • Controller通过调用Model层,自定义Service层,Event, Queue来完成自身的业务逻辑。但是在Controller层,尽量做到对于底层服务的底耦合,为了能够更好的测试,也尽量使用对象的依赖注入。

  • Controller层与其它层的一般关系如下

  Router ->> Controller : 数据请求
  Controller ->> Controller : 处理用户请求
  Controller ->> Model : 数据业务处理
  Model -> Model : 数据查询更新
  Model -> Service : 业务逻辑处理
  Controller ->> Service : 业务逻辑处理
  Service --> ClientAPI : 服务请求处理
  ClientAPI --> Service : 服务应答
  Service --> Controller : 业务处理结果
  Controller --> Router : 数据应答
  • 如果要实现程序异步机制,请使用Lumen提供的Queue功能。异步机制的使用可以提高API的应答效率,以下场景比如事件机制的接收处理,对于延时的任务机制,也需要通过Queue功能完成
  Router -> Controller :  数据请求
  Controller -> Controller : 处理请求
  Controller --> QueueJob : 任务添加Dispatcher
  Controller --> Router : 数据应答
  QueueJob -> QueueJob : 任务调度
  QueueJob -> JobProcedure : JOB处理
  JobProcedure -> Model : 数据应务处理
  • 如果编写与业务无关的类库、服务等应用,需要与上层的Controller/Model解耦,当需要有数据或者事件通知到上层应用,并让上层应用决定做出处理时,那么可以利用Event事件机制。
  Controller -> EventListener : 订阅事件
  MyService -> MyService : 业务处理
  MyService -> Event : 派发事件
  Event --> EventListener : 事件触发
  EventListener -> EventListener : 事件处理
  • Controller层的处理只作出正常的返回处理,而不对异常情况进行返回,遇到异常情况时,通过Exception的机制进行数据的返回。
public function dosth() {
   dosth1();
   dosth2();
   if($error) {
       throw new MYException('Error Message',SOMECODE);
   }
   $this->respond([..]);
}
  • BasicController,BaseModel有UtilToolMethods的相关方法,实现了以下的基本功能
索引 方法名 备注
1 arrValidate 实现以数组字典数据的验证
2 dispatchJob 派发事件
3 utilToArray 将对象转换为数组
4 getConfigValue 获得配置文件中的值
5 arrayEncode 将字典Hash成一个字符串,一般用来实现CacheKey
6 getEnv 获得环境变量名称: 有dev/testing/production/
7 envIsTesting 判断环境是否测试环境
8 envIsDemo 判断环境是否环境
9 envIsProduction 判断环境是否生产环境