Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a good hypermedia format using JMSSerializerBundle?

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?

like image 291
PatrikAkerstrand Avatar asked Sep 13 '12 13:09

PatrikAkerstrand


1 Answers

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.

like image 108
Lars Strojny Avatar answered Oct 03 '22 22:10

Lars Strojny