2

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

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

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

  • 我应该在序列化过程中注入一些额外的逻辑吗(如果是这样的话)?
  • 我是否应该使用要从原始实体公开的属性以及其他外部属性创建包装实体?
  • 我应该在序列化之前将属性添加isFresh到原始Pizza实体并填充到控制器中吗?
  • 我是否应该返回独立于实体数据的附加数据(例如在同级 JSON 属性中)?

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

4

2 回答 2

2

我认为您可以使用 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 方法

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

于 2014-04-08T10:17:33.040 回答
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);

对象序列化器将返回一个数组数组可以通过使用真正的序列化器(如. 如果您这样配置,它将自动执行此操作。JMS SerializerFOSRestBundle

于 2014-04-11T16:35:38.680 回答