atrauzzi / laravel-serializer
JMS Serializer 与 Laravel 的集成!
Requires
- php: >=5.4.0
- jms/serializer: dev-master
- laravel/framework: >=4.0
This package is not auto-updated.
Last update: 2022-02-01 12:37:45 UTC
README
将 JMS serializer 库绑定到 Laravel,并允许根据正常的 Laravel 配置约定定义模式。
设置
要将 Laravel Serializer 设置为在您的项目中使用,请按照设置 Laravel 包的常规步骤进行。
- 将
atrauzzi/laravel-serializer
添加到您的composer.json
文件中。 - 在您的项目根目录运行
composer update
。 - 编辑您的
app/config/app.php
文件,并在providers
数组的底部附近添加Atrauzzi\LaravelSerializer\JMSSerializerServiceProvider::class,
- 获取项目级别的配置副本
./artisan config:publish atrauzzi/laravel-serializer
Note: Because this package does not perform any data storage, no migrations are required.
配置
内部,JMS serializer 库使用元数据映射。通常这些通过 XML、YAML 或正在序列化的类上的注解进行配置。另一方面,Laravel Serializer 的观点是,这些定义应该位于业务对象外部,并保持对 Laravel 项目本地的格式。因此,映射存储为正常 Laravel 配置数组系统的一部分。
如果您希望覆盖此并配置序列化器使用默认或自定义元数据驱动程序工厂,您只需在依赖注入容器中重新绑定 JMS\Serializer\Builder\DriverFactoryInterface
。
映射
如果您打开上一步在设置过程中创建的 config.php
文件的副本,您将看到它已经包含了一个示例序列化器映射。
映射配置模式相当简单,遵循以下形式
[
'mappings' => [
'My\Namespace\Domain\User' => [
'attributes' => [
'id' => 'integer',
'name' => [
'type' => 'string'
]
]
]
]
]
每个 mappings
下的键都是将要序列化的对象的完全限定类名。每个类内 attributes
下的键是一个属性或修改器方法的名称(有关修改器的更多信息请参阅使用部分)。在 mappings
下指定的值可以是 array
、string
或未指定。当值为字符串时,该字符串将是该字段的类型。当值为数组时,可以为单个字段指定多个配置指令。没有值的键将获得最佳猜测默认映射配置。
使用
由于您正在寻找序列化数据,我将假设您已经在项目中使用了一些形式的领域对象。
在执行序列化时,映射配置中的每个字段指示一个属性或修改器方法,类似于可以在 Eloquent 模型上创建的修改器。也就是说,如果您使用任何其他 ORM 和/或 POPO,您也可以定义遵循相同约定的方法。
序列化是通过从 Laravel 容器请求 JMS\Serializer\Serializer
实例来完成的。一旦您有了这个实例,您就可以按照 正常的 JMS serializer 文档 使用它。
让我们假设以下映射配置
...
[
'attributes' => [
'firstName'
'fullName' => [
'type' => 'string'
]
]
]
...
并且,我们还将假设一个业务对象具有以下定义
protected $firstName;
protected $lastName;
public function getFullNameAttribute() {
return $this->userName . ' ' . $this->lastName;
}
您的控制器将类似于以下这样
/** @var \JMS\Serializer\Serializer */
protected $serializer;
/**
* @param \JMS\Serializer\Serializer $serializer
*/
public function __construct(
Serializer $serializer
) {
$this->serializer = $serializer;
}
public function myController() {
// ...
$serializedData = $this->serializer->serialize($myInstance, 'json');
// ...
}
在这个场景中,当序列化为JSON时,将生成以下模式
{
"_type": "...",
"first_name": "...",
"full_name": "... ..."
}
正如您所看到的,输出了firstName
,而fullName
是由firstName
和lastName
派生出来的。但是独立的lastName
属性没有被输出,因为在映射配置中未指定。您也可能注意到生成了一个_type
字段,以便于任何可能对混合和多态结果集感兴趣的消费者。
关注点分离
您可能会想到——尤其是如果您正在使用Doctrine——并不是所有的修改器都属于包含它们正在修改的数据的类。通常,修改可能是由于两个或更多关注点的环境组合的结果。最好的也是最常见的例子是在生成对象的规范URI时。理想情况下,您不应该在模型上编写getUri
方法,因为这会创建不良的隐式依赖。
在这些情况下,利用组合和创建一个可以由Laravel的依赖注入容器创建的类更为合理。在调用它们的__construct
方法后,将分配给这些类的实例。
class PostSerializer {
protected $uriGeneratorService;
protected $post;
public function __construct(UriGeneratorService $uriGeneratorService) {
$this->uriGeneratorService = $uriGeneratorService;
}
public function setPost(Post $post) {
$this->post = $post;
}
public function getUriAttribute() {
return $this->uriGeneratorService->getUriForPost($this->post);
}
}
鉴于上述示例,可以通过将数据向上传递的修改器输出来自Post
的附加属性。在这种情况下,PostSerializer
已经成为一种视图,通过保持合理关注点分离来帮助保持域类干净和可移植。
Eloquent
Laravel的默认ORM是Eloquent,它是一个方便的工具,用于操作查询和建模数据。作为副作用,它往往在模型类中捆绑了许多非域关注点。而不是忽略这些有用的元数据,这种集成尝试利用它来最小化在编写项目代码时的努力重复。以下是如果您使用Eloquent进行数据存储可以享受的一些快捷方式列表。
- 当存在时,Laravel Serializer会检测并使用修改器。
- 在元数据设置期间读取
Model
子类的$visible
属性。假设每个字段的最基本设置,这可能对您的需求来说已经足够,如果是这样,这意味着您不需要在模型类之外创建配置映射。
元数据
本库的一些文档和功能仍在不断发展。如果您想贡献或建议功能或改进,请毫不犹豫地打开github票据! :)
鸣谢
Laravel Serializer由Alexander Trauzzi创建和维护