loadsys/cakephp_serializers

将 CakePHP 响应序列化为 JSON 以及相应地将 JSON 反序列化为 CakePHP 数据数组的解决方案,主要用于构建使用 Ember 和 Ember Data 的 REST API。

安装次数: 3,395

依赖者: 0

建议者: 1

安全性: 0

星标: 6

关注者: 10

分支: 1

开放问题: 19

类型:cakephp-plugin

1.0.0-rc.4 2015-05-07 21:01 UTC

README

Latest Version Software License Build Status Coverage Status Total Downloads

将 CakePHP 响应序列化为 JSON 以及相应地将 JSON 反序列化为 CakePHP 数据数组的解决方案,主要用于构建使用 Ember 和 Ember Data 的 REST API。

此插件旨在匹配 Ember Data 和 DS.ActiveModelAdapter,用于序列化和反序列化 CakePHP 生成的响应。

关于任何实现细节的问题可以通过测试用例作为最终权威答案来回答。

目前此插件尚未完全准备好用于生产 - 请注意可能存在错误/问题。

此 README 被分为以下部分,其他 README 文档涵盖了某些主题。

  1. 基本用例
  2. 要求
  3. 安装
  4. 基本设置
  5. 错误和异常处理设置
  6. 自定义 Bake 模板
  7. 高级示例
  8. 贡献
  9. 许可证
  10. 版权

其他 README 文档

  1. 序列化
  2. 反序列化
  3. 异常

基本用例

此插件的基本概念是为序列化和反序列化 CakePHP 响应到 JSON 提供端到端解决方案。此插件主要针对与 ActiveModelAdapter 一起使用 Ember 和 Ember Data 而设计。

因此,将 CakePHP 模型数据数组序列化为

$data = array(
	'User' => array(
		'id' => 1,
		'username' => 'testusername',
		'first_name' => 'first',
		'last_name' => 'last',
		'is_active' => true,
	)
);

{
	"user": {
		"id": 1,
		"username": "testusername",
		"first_name": "first",
		"last_name": "last",
		"is_active": true,
	}
}

并执行反向操作,通过反序列化请求体中传递的数据

{
	"users": {
		"id": 1,
		"username": "testusername",
		"first_name": "first",
		"last_name": "last",
		"is_active": true,
	}
}

{
	"user": {
		"id": 1,
		"username": "testusername",
		"first_name": "first",
		"last_name": "last",
		"is_active": true,
	}
}

$this->request->data = array(
	'User' => array(
		'id' => 1,
		'username' => 'testusername',
		'first_name' => 'first',
		'last_name' => 'last',
		'is_active' => true,
	)
);

要求

  • PHP >= 5.4.0
  • CakePHP >= 2.3

安装

Composer

  • 运行以下 shell 命令
$ composer require loadsys/cakephp_serializers:dev-master

Git

git clone git@github.com:loadsys/CakePHP-Serializers.git Plugin/Serializers

基本设置

加载插件并确保 bootstrap 设置为 true

// Config/boostrap.php
CakePlugin::load('Serializers', array('bootstrap' => true));
// or
CakePlugin::loadAll(array(
	'Serializers' => array('bootstrap' => true),
));

如果您计划使用此插件来反序列化 HTTP 请求中的数据,则需要做出一些其他更改

// Config/boostrap.php
Configure::write('Dispatcher.filters', array(
	'Serializers.DeserializerFilter',
));

当反序列化数据并将 CakePHP 控制器设置为响应 REST HTTP 请求时,您还需要添加

// Config/routes.php
Router::mapResources(array(
	'{controller_name}',
));
Router::parseExtensions('json');

CakePHP 书籍中有更多关于如何使用 CakePHP 和此功能进行 REST API 的信息

错误和异常处理设置

错误和异常通过单独的 CakePHP 插件处理,通过 Composer 包含: SerializersErrors

请阅读那里的文档以获取更多具体信息。

修改您的 app/Config/core.php 文件以使用 SerializersErrors 中的自定义异常/错误处理。

Configure::write('Exception', array(
	'handler' => 'ErrorHandler::handleException',
	'renderer' => 'SerializersErrors.SerializerExceptionRenderer',
	'log' => true,
));

这做了两件事

  • 错误和异常以正确格式化的 JSON API、JSON 或 HTML 的形式输出,具体取决于请求类型
  • 允许使用与 Ember Data 异常相匹配的自定义异常来处理错误情况

自定义 Bake 模板

该项目中包含用于生成与 Serializers 插件一起工作的 CakePHP 控制器类的自定义 bake 模板。在生成控制器时使用 serializers 模板。

自定义 bake 模板包括使用上一节中的自定义异常类来提供符合 Ember Data 期望的反馈。

高级示例

我们可以序列化多个记录

$data = array(
	'User' => array(
		0 => array(
			'id' => 1,
			'username' => 'testusername',
			'first_name' => 'first',
			'last_name' => 'last',
			'is_active' => true,
		),
		1 => array(
			'id' => 2,
			'username' => 'testusername',
			'first_name' => 'first',
			'last_name' => 'last',
			'is_active' => true,
		),
	)
);

{
	"users": [
		{
			"id": 1,
			"username": "testusername",
			"first_name": "first",
			"last_name": "last",
			"is_active": true,
		},
		{
			"id": 2,
			"username": "testusername",
			"first_name": "first",
			"last_name": "last",
			"is_active": true,
		},
	]
}

即使有多个记录也可以序列化子模型记录

$data = array(
	'User' => array(
		0 => array(
			'id' => 1,
			'username' => 'testusername',
			'first_name' => 'first',
			'last_name' => 'last',
			'is_active' => true,
			'SecondaryModel' => array(
				"something" => "blahh",
			),
		),
		1 => array(
			'id' => 2,
			'username' => 'testusername',
			'first_name' => 'first',
			'last_name' => 'last',
			'is_active' => true,
			'SecondaryModel' => array(
				0 => array(
					"something" => "teasdf",
				),
				1 => array(
					"something" => "fgdfghdfg",
				),
			),
		),
	)
);

{
	"users": [
		{
			"id": 1,
			"username": "testusername",
			"first_name": "first",
			"last_name": "last",
			"is_active": true,
			"secondary_models": [
				{
					"something": "blahh"
				}
			]
		},
		{
			"id": 2,
			"username": "testusername",
			"first_name": "first",
			"last_name": "last",
			"is_active": true,
			"secondary_models": [
				{
					"something": "teasdf"
				},
				{
					"something": "fgdfghdfg"
				}
			]
		},
	]
}

反序列化多个记录和子模型记录的方式相同

{
	"users": [
		{
			"id" : 1,
			"username": "testusername",
			"first_name": "first",
			"last_name": "last",
			"is_active": true,
		},
		{
			"id": 2,
			"username": "testusername",
			"first_name": "first",
			"last_name": "last",
			"is_active": true,
		},
	]
}

$this->request->data = array(
	'User' => array(
		0 => array(
			'id' => 1,
			'username' => 'testusername',
			'first_name' => 'first',
			'last_name' => 'last',
			'is_active' => true,
		),
		1 => array(
			'id' => 2,
			'username' => 'testusername',
			'first_name' => 'first',
			'last_name' => 'last',
			'is_active' => true,
		),
	)
);

即使有多个记录也可以反序列化子模型记录

{
	"users": [
		{
			"id": 1,
			"username": "testusername",
			"first_name": "first",
			"last_name": "last",
			"is_active": true,
			"secondary_models": {
				"something": "blahh",
			}
		},
		{
			"id": 2,
			"username": "testusername",
			"first_name": "first",
			"last_name": "last",
			"is_active": true,
			"secondary_models": [
				{
					"something": "teasdf",
				},
				{
					"something": "fgdfghdfg",
				}
			]
		},
	]
}

$this->request->data = array(
	'User' => array(
		0 => array(
			'id' => 1,
			'username' => 'testusername',
			'first_name' => 'first',
			'last_name' => 'last',
			'is_active' => true,
			'SecondaryModel' => array(
				"something" => "blahh",
			),
		),
		1 => array(
			'id' => 2,
			'username' => 'testusername',
			'first_name' => 'first',
			'last_name' => 'last',
			'is_active' => true,
			'SecondaryModel' => array(
				0 => array(
					"something" => "teasdf",
				),
				1 => array(
					"something" => "fgdfghdfg",
				),
			),
		),
	)
);

如果存在要序列化的数据的第二个顶级模型,则将其移动到第一个模型的属性中

$data = array(
	'User' => array(
		'id' => 1,
		'username' => 'testusername',
		'first_name' => 'first',
		'last_name' => 'last',
		'is_active' => true,
	),
	'SecondModel' => array(
		'id' => 1,
		'name' => 'asdflkjasdf'
	),
);

{
	"user": {
		"id": 1,
		"username": "testusername",
		"first_name": "first",
		"last_name": "last",
		"is_active": true,
		"second_models": [
			{
				'id': 1,
				'name': 'asdflkjasdf'
			}
		]
	}
}

如果数据中存在第二个顶级模型进行反序列化,则将其忽略

{
	"users": {
		"id": 1,
		"username": "testusername",
		"first_name": "first",
		"last_name": "last",
		"is_active": true,
	},
	"second_models": {
		"id": 1,
		"something": "data"
	}
}

$this->request->data = array(
	'User' => array(
		'id' => 1,
		'username' => 'testusername',
		'first_name' => 'first',
		'last_name' => 'last',
		'is_active' => true,
	)
);

贡献

报告问题

请使用GitHub Issues来列出任何已知的缺陷或问题。

开发

在开发此插件时,请进行分支操作,并为任何新开发提交一个PR。

可以通过以下命令运行插件的完整测试套件

./lib/Cake/Console/cake test Serializers AllSerializers

许可证

MIT

版权

Loadsys Web Strategies 2015