Rest 向序列化对象添加自定义属性
我正在为web服务开发RESTful API。我需要公开一些不属于实体本身的属性 例如,我有一个Rest 向序列化对象添加自定义属性,rest,symfony,fosrestbundle,jmsserializerbundle,jms-serializer,Rest,Symfony,Fosrestbundle,Jmsserializerbundle,Jms Serializer,我正在为web服务开发RESTful API。我需要公开一些不属于实体本身的属性 例如,我有一个Pizza实体对象,它有自己的size和name属性。我用FOSRestBundle和JMSSerializer以JSON格式输出它。我已经为这个实体设置了属性注释,以便通过序列化组公开所需的属性,它工作得很好 但是我需要添加一些不属于实体本身的属性。例如,我希望我的pizza具有属性:isFresh,该属性由一些PizzaService::isFresh(pizza$pizza)服务确定。我该怎么做
Pizza
实体对象,它有自己的size
和name
属性。我用FOSRestBundle和JMSSerializer以JSON格式输出它。我已经为这个实体设置了属性注释,以便通过序列化组公开所需的属性,它工作得很好
但是我需要添加一些不属于实体本身的属性。例如,我希望我的pizza
具有属性:isFresh
,该属性由一些PizzaService::isFresh(pizza$pizza)
服务确定。我该怎么做
- 我是否应该向序列化过程注入一些额外的逻辑(如果是的话,如何注入)
- 我是否应该创建一个包装器实体,其中包含我希望从原始实体公开的属性以及其他外部属性
- 在序列化之前,我是否应该将属性
添加到原始isFresh
实体并填充到控制器中Pizza
- 我是否应该独立于实体数据返回其他数据(例如在同级JSON属性中)
换句话说:围绕这个问题的最佳实践是什么?你能举个例子吗?谢谢。我想您可以通过VirtualProperty注释来实现这一点:
/**
* @JMS\VirtualProperty
* @return boolean
*/
public function isFresh (){
...
}
编辑:另一个带有访问者注释的解决方案
/** @Accessor(getter="getIsFresh",setter="setIsFresh") */
private $isFresh;
// ...
public function getIsFresh()
{
return $this->isFresh;
}
public function setIsFresh($isFresh)
{
$this->isFresh= $isFresh;
}
在控制器中,调用setIsFresh方法
(请参阅)我决定创建自己的类来序列化实体 下面是一个例子:
class PizzaSerializer implements ObjectSerializerInterface
{
/** @var PizzaService */
protected $pizzaService;
/**
* @param PizzaService $pizzaService
*/
public function __construct(PizzaService $pizzaService)
{
$this->pizzaService = $pizzaService;
}
/**
* @param Pizza $pizza
* @return array
*/
public function serialize(Pizza $pizza)
{
return [
'id' => $pizza->getId(),
'size' => $pizza->getSize(),
'name' => $pizza->getName(),
'isFresh' => $this->pizzaService->isFresh($pizza),
];
}
}
您只需将DC配置为将PizzaService
注入到对象序列化程序中,然后从控制器像这样调用它:
$pizza = getPizzaFromSomewhere();
$pizzaSerializer = $this->get('serializer.pizza');
return $pizzaSerializer->serialize($pizza);
对象序列化程序将返回一个数组,该数组可以通过使用真正的序列化程序(如
JMS serializer
)轻松转换为JSON、XML、YAML或任何其他格式FOSRestBundle
将自动执行此操作,如果您将其配置为这样。此问题也与此虚拟财产依赖于服务有关,似乎这只是答案的一部分。也许你也可以设想一种方法来实现它?是的,你是对的。我认为“我应该在序列化之前将属性isFresh添加到原始Pizza实体并填充到控制器中吗?”是更好的解决方案。为此,我添加了另一种访问器注释方式嘿,谢谢你的回答。为什么你认为这种方法更好?其他方法的缺点是什么?您是否在实践中实施了此设计?