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

49

假设我想创建一个类似于以下内容的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>

假设有一个领域模型,它看起来像以下这样:

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

  [..]
}

还有一个类似于货币类的东西:

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

class Money
{
  /**
   * @var string
   */
  private $currency;
  /**
   *
   */
  private $amount;
}
现在,我有几个问题。创建一个类似以下的响应将相当简单。
<?xml version="1.0" encoding="utf‐8"?>
<product>
  <id>1234</id>
  <name>Red Stapler</name>
  <price currency="EUR">3.14</price>
</product>
使用注释、XML或YAML来告诉JMSSerializerBundle如何序列化Product对象。然而,实体不应指定 xmlns:atom < atom:link>条目,因为它不应该具有其所在位置的概念。您还可以想象带有不同 rel 属性的更多链接,例如edit
一种解决方案是创建一个监听序列化特定对象事件的服务,并根据需要添加这些属性和标记。该服务可以使用DI获取 Request Router 等服务以生成适合所请求格式的链接。例如,在XML响应中,它可以将适当类型设置为 application/media-format+xml ,而在json响应中,它可以生成类似以下内容:
"links": [
   {
     "rel": "payment", 
     "type": "application/media-format+json", 
     "href": "[...]"
   }
]
现在,在JMSSerializerBundle的文档中,我发现有@PreSerialize@PostSerialize的注释,但它们似乎只能调用正在被序列化的对象上的方法。
有人知道这是否可以实现吗?或者我必须使用像Twig这样的模板引擎并手动创建XML响应?

非常有趣的问题。在稍微探索一下后,我认为没有其他解决方案,除了使用仅用于序列化的附加属性来污染您的实体... 在捆绑包中似乎缺少处理特定对象的完整序列化的可能性与另一个类。 - room13
你可以在这里查看1:指定属性的组。还有这里2:JMS序列化程序包-复杂生成值。 - Pratik Butani
1个回答

3

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

我建议你研究一下FSCHateoasBundle,以实现一个漂亮的超媒体格式来构建你的API。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接