symfony - ¿Cómo crear un buen formato hipermedia utilizando JMSSerializerBundle?
symfony-2.1 hateoas (1)
Digamos que quiero crear una respuesta XML que se parecerá a la siguiente:
<?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>
Dado un modelo de dominio que se parece a lo siguiente:
<?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;
[..]
}
Y una clase de dinero a lo largo de las líneas de:
<?php
// Money.php
namespace Acme/Bundle/ProductBundle/Money;
class Money
{
/**
* @var string
*/
private $currency;
/**
*
*/
private $amount;
}
Ahora, a mis preguntas. Sería bastante simple crear una respuesta que se parece a la siguiente
<?xml version="1.0" encoding="utf‐8"?>
<product>
<id>1234</id>
<name>Red Stapler</name>
<price currency="EUR">3.14</price>
</product>
usando anotaciones, XML o YAML para decirle a JMSSerializerBundle cómo serializar el objeto Producto. Sin embargo, la entidad no debe especificar las entradas xmlns:atom
y <atom:link>
, ya que no debe tener un concepto de cómo y dónde se encuentra. También podría imaginar más enlaces con diferentes rel
, como edit
.
Una solución que se me ocurre es un servicio que escucha eventos de serialización para objetos específicos y agrega estos atributos y etiquetas según corresponda. El servicio podría usar DI para obtener la Request
, el Servicio de Router
, etc., para generar estos enlaces en un formato que sea adecuado para el formato solicitado. IE en una respuesta XML, podría establecer el tipo apropiado para application/media-format+xml
, mientras que en una respuesta json, podría generar algo así como
"links": [
{
"rel": "payment",
"type": "application/media-format+json",
"href": "[...]"
}
]
Ahora, en la documentación de JMSSerializerBundle , encuentro anotaciones para @PreSerialize
y @PostSerialize
, pero parece que solo pueden invocar métodos en el objeto que se está serializando.
¿Alguien sabe cómo / si esto se puede lograr? ¿O tengo que usar un motor de plantillas como Twig y crear manualmente la respuesta XML?
El paquete de serializador solo puede no ser suficiente para esta situación, ya que solo se trata de serialización y deserialización, no de tareas semánticas más complejas.
Sugiero que busque en FSCHateoasBundle para implementar un formato bastante hipermedia para su API.