如何使用JMSSerializerBundle创建一个好的超媒体格式?

Pat*_*and 48 hateoas symfony hypermedia symfony-2.1 jmsserializerbundle

假设我想创建一个类似于以下内容的XML响应:

<?xml version="1.0" encoding="utf?8"?>
<product xmlns="urn:com.acme.prods" xmlns:atom="http://www.w3.org/2005/xlink">
  <id>1234</id>
  <name>Red Stapler</name>
  <price currency="EUR">3.14</price>
  <atom:link rel="payment" type="application/com.acme.shop+xml"
             href="http://acme.com/products/1234/payment" />
</product>
Run Code Online (Sandbox Code Playgroud)

给定一个类似于以下内容的域模型:

<?php
// Product.php
namespace Acme\Bundle\ProductBundle\Entity;
use Acme\Bundle\ProductBundle\Money\Money;

class Product
{
  /**
   * @var integer
   */
  private $id;

  /**
   * @var string
   */
  private $name;

  /**
   * @var Money
   */
  private $price;

  [..]
}
Run Code Online (Sandbox Code Playgroud)

和金钱类一样:

<?php
// Money.php
namespace Acme\Bundle\ProductBundle\Money;

class Money
{
  /**
   * @var string
   */
  private $currency;
  /**
   *
   */
  private $amount;
}
Run Code Online (Sandbox Code Playgroud)

现在,我的问题.创建如下所示的响应非常简单

<?xml version="1.0" encoding="utf?8"?>
<product>
  <id>1234</id>
  <name>Red Stapler</name>
  <price currency="EUR">3.14</price>
</product>
Run Code Online (Sandbox Code Playgroud)

使用注释,XML或YAML告诉JMSSerializerBundle如何序列化Product-object.但是,实体不应指定xmlns:atom<atom:link>条目,因为它应该没有关于它的位置和位置的概念.您还可以想象使用不同rel-attributes的更多链接,例如edit.
想到的一个解决方案是一个侦听特定对象的序列化事件的服务,并根据需要添加这些属性和标记.该服务可以使用DI得到的保持Request,Router-service等产生的格式适用于请求的格式这些链接.在XML响应中的IE,它可以设置适当的类型application/media-format+xml,而在json响应中,它可以生成类似的东西

"links": [
   {
     "rel": "payment", 
     "type": "application/media-format+json", 
     "href": "[...]"
   }
]
Run Code Online (Sandbox Code Playgroud)

现在,对于JMSSerializerBundle的文档,我找了注释@PreSerialize,和@PostSerialize,但他们似乎只能够调用被序列化的对象上的方法.
有谁知道如何实现这一目标?或者我是否必须使用模板引擎(如Twig)并手动创建XML响应?

Lar*_*jny 3

单独的 Serializer Bundle 可能不足以满足这种情况,因为它只涉及序列化和反序列化,而不是更复杂的语义任务。

我建议研究FSCHateoasBundle来为您的 API 实现一个漂亮的超媒体格式。