将自定义属性添加到序列化对象

时间:2014-04-08 02:00:08

标签: rest symfony fosrestbundle jmsserializerbundle jms-serializer

我正在为Web服务开发RESTful API。我需要公开一些不属于实体本身的属性。

例如,我有一个Pizza实体对象,它拥有自己的sizename属性。我用 FOSRestBundle JMSSerializer 以JSON格式输出它。我已经为此实体设置了属性注释,以通过序列化组公开所需的属性,并且它工作得很好。

但我需要添加一些不属于实体本身的属性。例如,我希望我的pizza拥有由isFresh服务确定的属性PizzaService::isFresh(Pizza $pizza)。我该怎么做?

  • 我是否应该为序列化过程注入一些额外的逻辑(如果是这样的话)?
  • 我应该创建一个包装器实体,其中包含我想要从原始实体公开的属性以及其他外部属性吗?
  • 我应该将属性isFresh添加到原始Pizza实体并在序列化之前填入控制器吗?
  • 我是否应该返回与实体数据无关的其他数据(例如,在兄弟JSON属性中)?

换句话说:围绕这个问题的最佳做法是什么?你能提供一些例子吗?谢谢。

2 个答案:

答案 0 :(得分:2)

我认为你可以使用VirtualProperty注释做到这一点:

/**
 * @JMS\VirtualProperty
 * @return boolean
 */
public function isFresh (){
     ...
}

编辑:使用Accessor注释的另一个解决方案

/** @Accessor(getter="getIsFresh",setter="setIsFresh") */
private $isFresh;

// ...
public function getIsFresh()
{
    return $this->isFresh;
}

public function setIsFresh($isFresh)
{
    $this->isFresh= $isFresh;
}

在控制器中,调用setIsFresh方法

(见http://jmsyst.com/libs/serializer/master/reference/annotation

答案 1 :(得分:0)

我决定创建自己的类来序列化实体。

以下是例子:

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);

对象序列化程序将返回一个数组,该数组可以使用真正的序列化程序轻松转换为 JSON XML YAML 或任何其他格式比如JMS Serializer。如果您进行了配置,FOSRestBundle会自动执行此操作。