最近在开发项目的过程中,突然间遇到一些业务场景,比如在一些实际的业务中,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无法处理数组中的对象。所以建议返回数据的时候可以序列化数组
其实Yii::createObject($this->serializer)->serialize($videos);这个也就是yii/rest/Serializer最终实现的方法,在每个函数的返回我们提前把它实现了,将数据提供者的数据序列为数组,这样我们在其他的函数调用这个函数的时候,返回的数据就是数组,可以与其他的数据重新整合成一个大数组,最终返回。
当然,如果一个函数,没有在其他的函数中调用,那么可以将其直接返回数据提供者对象,例如:
return $videos;
请求用户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;