Symfony 在要序列化的实体上添加动态属性
我有这个RESTAPI。每当请求通过id(/resource/{id})获取资源时,我都希望动态地在该对象上添加Symfony 在要序列化的实体上添加动态属性,symfony,jms-serializer,Symfony,Jms Serializer,我有这个RESTAPI。每当请求通过id(/resource/{id})获取资源时,我都希望动态地在该对象上添加权限数组(实体本身没有该字段) 我想到的是这个事件监听器。它检查控制器返回的结果: class PermissionFinderListener { ... public function onKernelView(GetResponseForControllerResultEvent $event) { $object = $event->g
权限
数组(实体本身没有该字段)
我想到的是这个事件监听器。它检查控制器返回的结果:
class PermissionFinderListener {
...
public function onKernelView(GetResponseForControllerResultEvent $event) {
$object = $event->getControllerResult();
if (!is_object($object) || !$this->isSupportedClass($object)) {
return;
}
$permissions = $this->permissionFinder->getPermissions($object);
$object->permissions = $permissions;
$event->setControllerResult($object);
}
....
}
问题是JMS序列化程序在序列化时选择了这个动态属性。我尝试在JMS序列化程序上创建onPostSerialize
事件订阅服务器,但是没有明确的方法来检查这是GET ONE
还是GET COLLECTION
请求。我不需要在GET COLLECTION
上使用这种行为,而且它会对集合序列化产生巨大的性能影响。另外,我不想创建任何具有权限
属性的基本实体类
也许还有其他方法来处理这种情况?我可以想象虚拟财产和序列化组的组合: 向实体添加属性,如:
/**
* @Serializer\VirtualProperty
* @Serializer\SerializedName("permissions")
* @Serializer\Groups({"includePermissions"}) */
*
* @return string
*/
public function getPermissions()
{
return $permissionFinder->getPermissions($this);
}
然后,您只需要在特殊情况下序列化“includePermissions”组(请参阅)
如果您没有从实体访问$permissionFinder的权限,您还可以在序列化实体之前从控制器/服务设置实体的权限属性
编辑:
这是更多的代码来演示我所说的包装实体和将VirtualProperty与序列化组一起使用的意思。这段代码根本没有经过测试——它基本上是我们正在使用的手动复制和剥离版本。所以请把它当作一个想法来使用
1) 为实体创建类似包装类的内容:
<?php
namespace Acquaim\ArcticBundle\Api;
use JMS\Serializer\Annotation as JMS;
/**
* Class MyEntityApi
*
* @package My\Package\Api
*/
class MyEntityApi
{
/**
* The entity which is wrapped
*
* @var MyEntity
* @JMS\Include()
*/
protected $entity;
protected $permissions;
/**
* @param MyEntity $entity
* @param Permission[] $permissions
*/
public function __construct(
MyEntity $entity,
$permissions = null)
{
$this->entity = $entity;
$this->permissions = $permissions;
}
/**
* @Serializer\VirtualProperty
* @Serializer\SerializedName("permissions")
* @Serializer\Groups({"includePermissions"})
*
* @return string
*/
public function getPermissions()
{
if ($this->permissions !== null && count($this->permissions) > 0) {
return $this->permissions;
} else {
return null;
}
}
/**
* @return object
*/
public function getEntity()
{
return $this->entity;
}
}
我希望ro避免更改或耦合我的实体,那么将您的实体包装成一个具有虚拟财产的实体怎么样?e、 g.通过扩展ViewHandler或类似的东西?那么你就不需要使用事件监听器了。也许你可以用一些代码来说明你是什么样的人suggesting@nn4n4s:已添加示例,请检查
YourController:
$myEntity = new Entity();
$permissions = $this->get('permission_service')->getPermissions();
$context = SerializationContext::create()->setGroups(array('includePermissions'));
$myEntityApi = new MyEntityApi($myEntity,$permissions);
$view = $this->view($myEntityApi, 200);
$view->setSerializationContext($context);
return $this->handleView($view);