天天看点

yii2-restful的接口优化和实现互相调用

最近在开发项目的过程中,突然间遇到一些业务场景,比如在一些实际的业务中,restful的接口是分别对应一种请求的资源的,比如在一个首页内容页面上我们需要请求用户users,分类category,视频列表videos,在这里其实是可以通过三个restful的接口实现:

请求用户users:http://host/users

请求分类category: http://host/categorys

请求资源:http://host/videos

在这种情况下,其实请求之后都能够返回json数据,然后再前端显示数据,在网站的首页,一般都是比较多资源要显示的,那么就会产生更多的http请求,这对于网站来说,意味消耗更多的资源,增加服务器力的压力,那么,有没有一种方法可以优化一下呢?

其实我们可以在定义一个restful的接口,主要实现是将将上面的三种功能综合实现,然后统一返回json数据。

比如http://host/home,当然路由对应的操作就是actionIndex

下面说一下在yii2的restful中的实现用法:

//获取首页内容

public function actionIndex() {

//调用

       $user = $this->actionUser();

//调用

       $category = $this->actionCatrgory();

  //调用

       $videos = $this->actionVideo();

//将序列化后数组重组成一个大数组,返回数据

       return ['user'=>$user,'category'=>$category,'video'=>$videos];

}

//获取用户

public function actionUser() {

       $modelClass = $this->modelClass;

        // 

        $data = new ActiveDataProvider([

            'query' => $modelClass::find()->asArray(), 

            'pagination' => [

                'pageSize' => 6,

            ],

        ]);

        // 序列化对象为数组

        return Yii::createObject($this->serializer)->serialize($data); 

    }

//获取分类

public function actionCatrgory() {

       $modelClass = $this->modelClass;

        // 

        $category = new ActiveDataProvider([

            'query' => $modelClass::find()->asArray(),

        ]);

        // 序列化对象为数组

        return Yii::createObject($this->serializer)->serialize($category); 

    }

//获取视频

public function actionVideo() {

       $modelClass = $this->modelClass;

        // 

        $videos = new ActiveDataProvider([

            'query' => $modelClass::find()->asArray(),

        ]);

        // 序列化对象为数组

        return Yii::createObject($this->serializer)->serialize($videos); 

    }

在上面的方法中,我们依然定义了每一个restful接口,每一个接口都可以单独访问,因为对于ActiveDataProvider这个实例,我们是可以直接返回ActiveDataProvider这个实例的,比如:

//获取视频

public function actionVideo() {

       $modelClass = $this->modelClass;

        // 

        $videos = new ActiveDataProvider([

            'query' => $modelClass::find()->asArray(),

        ]);

        // 直接返回数据提供者对象,没有序列化为数组

        return $videos; 

 }

可以看到,直接返回$videos这个视频的数据提供实例,我们依然可以通过http://host/videos的url访问,因为在响应返回的时候,yii/rest/Serializer会对数据提供这对象序列化为数组,准确地说,yii/rest/Serializer只符合对数据提供者对象实现序列化。但是,在actionIndex中,$videos = $this->actionVideo();返回的是数据提供者对象,那么再把这个对象整合在一个返回数组中return ['user'=>$user,'category'=>$category,'video'=>$videos];

这时,yii/rest/Serializer同样会对返回的数组进行json处理,但是'video'这个键对应的videos这个数据提供者对象并不会显示我们期待的那样,因为yii/rest/Serializer无法处理数组中的对象。所以建议返回数据的时候可以序列化数组

return Yii::createObject($this->serializer)->serialize($videos);

而不是直接返回数据对象

其实Yii::createObject($this->serializer)->serialize($videos);这个也就是yii/rest/Serializer最终实现的方法,在每个函数的返回我们提前把它实现了,将数据提供者的数据序列为数组,这样我们在其他的函数调用这个函数的时候,返回的数据就是数组,可以与其他的数据重新整合成一个大数组,最终返回。

当然,如果一个函数,没有在其他的函数中调用,那么可以将其直接返回数据提供者对象,例如:

return $videos;