[Yii2笔记]071 RESTful的响应格式(Response Formatting) [ 技术分享 ]
说明
学习Yii Framework 2(易2框架)的过程是漫长的,也是充满乐趣的,以下是我学习Yii2框架时对官网英文资料(请参见原文网址)的翻译和代码实现,提供了较完整的代码,供你参考。不妥之处,请多多指正!
原文网址:
http://www.yiiframework.com/doc-2.0/guide-rest-response-formatting.html
本文主题:RESTful的响应格式(Response Formatting)
当处理一个RESTful API请求时,一个应用通常会按照以下步骤来处理响应格式: 1)找出可能影响响应格式的不同因素,例如媒体类型,语言,版本等等,这个过程被称为内容协商(content negotiationi)。 2)转换资源对象为数组,在Resources章节已描述过,此项操作由yii\rest\Serializer来完成。 3)根据内容协商中定义的格式将数组转换为一个字符串,此项操作由response应用组件的formatters属性注册的response formatters来完成。
1、内容协商(Content Negotiation)
Yii使用yii\filters\ContentNegotiator过滤器来支持内容协商,RESTful API基础控制器类yii\rest\Controller使用contentNegotiator名称来加载这个过滤器,此过滤器提供了与语言协商相同的响应格式协商,例如,如果一个RESTful API请求包含以下头信息: Accept:application/json;q=1.0,/;q=0.1s 此为注释符结束*/ 要获得一个JSON格式的响应,代码如下:
$curl -i -H "Accept:application/json;q=1.0,*/*;q=0.1" "http://localhost/users"
HTTP/1.1 200 OK
Date: Sun, 02 Mar 2014 05:31:43 GMT
Server: Apache/2.2.26 (Unix) DAV/2 PHP/5.4.20 mod_ssl/2.2.26 OpenSSL/0.9.8y
X-Powered-By: PHP/5.4.20
X-Pagination-Total-Count: 1000
X-Pagination-Page-Count: 50
X-Pagination-Current-Page: 1
X-Pagination-Per-Page: 20
Link: <http://localhost/users?page=1>; rel=self,
<http://localhost/users?page=2>; rel=next,
<http://localhost/users?page=50>; rel=last
Transfer-Encoding: chunked
Content-Type: application/json; charset=UTF-8
[
{
"id": 1,
...
},
{
"id": 2,
...
},
...
]
实例
$ curl -i -H "Accept:application/json;q=1.0,*/*;q=0.1" "http://localhost:8082/u
ser/5"
HTTP/1.1 200 OK
Date: Fri, 12 May 2017 06:13:53 GMT
Server: Apache/2.4.20 (Win64) OpenSSL/1.0.2g PHP/5.6.20
X-Powered-By: PHP/5.6.20
Content-Length: 333
Content-Type: application/json; charset=UTF-8
{"id":5,"username":"oakala","email":"allaa@163.net","createdAt":1461664500,"upda
ted_at":1473762490,"status":4,"_links":{"self":{"href":"http://localhost:8082/us
er/5"},"edit":{"href":"http://localhost:8082/user/5"},"profile":{"href":"http://
localhost:8082/user/profile/view?id=5"},"index":{"href":"http://localhost:8082/u
ser/users"}}}
User@User-PC MINGW32 /d/phpwork/b2b/imall (ycjnx)
$
此场景的运行过程:在一个RESTful API控制器动作执行之前,yii\filters\ContentNegotiator过滤器将检查请求之中的Accept的HTTP头信息,并设置响应格式为'json'。在动作执行后,将返回结果资源对象或集合,yii\rest\Serializer将转换结果为一个数组,最后,yii\web\JsonResponseFormatter将序列化数组为一个JSON字符串,并将它包含到响应主体中。 默认情况下,RESTful API支持JSON和XML格式,如果要支持一种新格式,你需要在API控制器类中配置contentNegotiator过滤器的formats属性,代码如下:
use yii\web\Response;
public function behaviors(){
$behaviors=parent::behaviors();
$behaviors['contentNegotiator']['formats']['text/html']=Response::FORMAT_HTML;
return $behaviors;
}
formats属性的键名是MIME类型支持的,键值是对应的响应格式名称,此格式必须是yii\web\Response::$fomatters 所支持的。
2、数据序列化(Data Serializing)
如上所述,yii\rest\Serializer是将资源对象或集合转为数组的核心步骤,它能识别实现yii\base\Arrayable以及yii\data\DataProviderInterface接口的对象,前者由资源对象实现,后者由资源集合实现。
你可以通过数组设置yii\rest\Controller::$serializer 属性来配置序列化器。例如,有时你可能想要通过在响应主体中包含分页信息的方式来简化客户端的开发,可以配置yii\rest\Serializer::$collectionEnvelope 属性来实现,代码如下:
use yii\rest\ActiveController;
class UserController extends ActiveController{
public $modelClass='app\models\User';
public $serializer=[
'class' =>'yii\rest\Serializer',
'collectionEnvelope'=>'items',
];
}
输入http://localhost/users,你也可以得到以下响应:
HTTP/1.1 200 OK
Date: Sun, 02 Mar 2014 05:31:43 GMT
Server: Apache/2.2.26 (Unix) DAV/2 PHP/5.4.20 mod_ssl/2.2.26 OpenSSL/0.9.8y
X-Powered-By: PHP/5.4.20
X-Pagination-Total-Count: 1000
X-Pagination-Page-Count: 50
X-Pagination-Current-Page: 1
X-Pagination-Per-Page: 20
Link: <http://localhost/users?page=1>; rel=self,
<http://localhost/users?page=2>; rel=next,
<http://localhost/users?page=50>; rel=last
Transfer-Encoding: chunked
Content-Type: application/json; charset=UTF-8
{
"items": [
{
"id": 1,
...
},
{
"id": 2,
...
},
...
],
"_links": {
"self": {
"href": "http://localhost/users?page=1"
},
"next": {
"href": "http://localhost/users?page=2"
},
"last": {
"href": "http://localhost/users?page=50"
}
},
"_meta": {
"totalCount": 1000,
"pageCount": 50,
"currentPage": 1,
"perPage": 20
}
}
Controlling JSON output(控制JSON输出)
由JsonResponseFormatter类生成的JSON响应使用的是内置的JSON helper,此格式化器可以使用不同的选项来配置,这些选项如$prettyPrint(在开发中使用广泛的具有很好的可读性的响应),或者$encodeOptions控制JSON编码的输出。
格式化器可以在应用配置的response应用组件的formatters属性中被配置,代码如下:
'response'=>[
'formatters'=>[
\yii\web\Resopnse::FORMAT_JSON=>[
'class' =>'yii\web\JsonResponseFormatter',
'prettyPrint'=>YII_DEBUG,
'encodeOptions'=>JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE,
],
],
]
当使用DAO从一个数据库返回数据时,所有的数据都是字符串格式,而不是期望的格式,如数值不是JSON格式中可以表示的数字。当使用ActiveRecord层从数据库获取数据时,在yii\db\ActiveRecord::populateRecord()中从数据库加载数据时,数字列的值将被转换为整数型。
(全文完)
共 0 条回复
阿江
最后登录:2024-03-03
在线时长:186小时21分
- 粉丝94
- 金钱16816
- 威望160
- 积分20276