Lets say I want to create an XML-response that will looks something like the following:
<?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>
Given an domain model that looks something like the following:
<?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; [..] }
And a money-class along the lines of:
<?php // Money.php namespace Acme\Bundle\ProductBundle\Money; class Money { /** * @var string */ private $currency; /** * */ private $amount; }
Now, to my questions. It would be pretty simple to create a response that looks like the following
<?xml version="1.0" encoding="utf‐8"?> <product> <id>1234</id> <name>Red Stapler</name> <price currency="EUR">3.14</price> </product>
using either annotations, XML or YAML to tell JMSSerializerBundle how to serialize the Product-object. However, the xmlns:atom
and <atom:link>
entries should not be specified by the entity, since it should have no concept of how and where it is located. You could also imagine more links with different rel
-attributes, such as edit
.
One solution that comes to mind would be a service that listens to serialization events for specific objects, and adds these attributes and tags as appropriate. The service could use DI to get hold of the Request
, Router
-service etc to generate these links in a format that is suitable for the requested format. I.E in an XML-response, it could set the appropriate type to application/media-format+xml
, whereas in a json-response, it could generate something like
"links": [ { "rel": "payment", "type": "application/media-format+json", "href": "[...]" } ]
Now, in the documentation for JMSSerializerBundle, I find annotations for @PreSerialize
, and @PostSerialize
, but they seem to only be able to call methods on the object being serialized.
Does anyone know how/if this can be achieved? Or do I have to use a templating engine such as Twig and manually create the XML-response?
The Serializer Bundle alone might not be enough for this situation as it is only concerned with serialization and deserialization, not more complex semantical tasks.
I would suggest looking into FSCHateoasBundle to implement a pretty hypermedia format for your API.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With