2012-09-13 20 views
48

Powiedzmy chcę utworzyć XML-odpowiedź, która będzie wyglądać jak poniżej:Jak stworzyć dobry format hipermedialny za pomocą JMSSerializerBundle?

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

Biorąc pod uwagę model domeny, który wygląda mniej więcej tak:

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

    [..] 
} 

a pieniędzy klasie zgodnie z:

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

class Money 
{ 
    /** 
    * @var string 
    */ 
    private $currency; 
    /** 
    * 
    */ 
    private $amount; 
} 

Teraz, na moje pytania. Byłoby to dość proste, aby utworzyć odpowiedź, która wygląda następująco

<?xml version="1.0" encoding="utf‐8"?> 
<product> 
    <id>1234</id> 
    <name>Red Stapler</name> 
    <price currency="EUR">3.14</price> 
</product> 

przy użyciu adnotacji XML lub YAML powiedzieć JMSSerializerBundle jak serializacji obiektu wyrobu. Jednak jednostki nie powinny określać wpisów xmlns:atom i <atom:link>, ponieważ nie powinny one zawierać pojęcia o tym, w jaki sposób jest ono zlokalizowane. Możesz także wyobrazić sobie więcej linków z różnymi atrybutami rel, takich jak edit.
Jednym z rozwiązań, które przychodzi na myśl, jest usługa, która nasłuchuje zdarzeń serializacji dla konkretnych obiektów i odpowiednio dodaje te atrybuty i tagi. Usługa może korzystać z DI, aby uzyskać dostęp do usługi Request, Router, aby wygenerować te łącza w formacie odpowiednim dla żądanego formatu. IE w XML-odpowiedzi, to może ustawić odpowiedni typ do application/media-format+xml, natomiast w JSON odpowiedzi, to może generować coś podobnego

"links": [ 
    { 
    "rel": "payment", 
    "type": "application/media-format+json", 
    "href": "[...]" 
    } 
] 

Teraz, w the documentation for JMSSerializerBundle uważam adnotacje dla @PreSerialize i @PostSerialize, ale wydają się być w stanie wywoływać tylko metody na serializowanym obiekcie.
Czy ktoś wie, jak/jeśli można to osiągnąć? Czy muszę użyć silnika szablonowego takiego jak Twig i ręcznie utworzyć odpowiedź XML?

+0

Bardzo interesujące pytanie. Po poklepaniu się trochę, nie ma innego rozwiązania, a następnie zanieczyszczenie twojego obiektu dodatkowymi atrybutami używanymi tylko do serializacji ... To, czego wydaje się brakować w pakiecie, to możliwość obsłużenia całej serializacji danego obiektu innym klasa. – room13

+0

[można sprawdzić tutaj 1: określ-group-per-atrybutu] [1] [Również tutaj 2: JMS serializer wiązka kompleks generowane wartość] [2] [ 1]: http://stackoverflow.com/questions/13665369/jmsserializerbundle-specify-group-per-atrybut [2]: http://stackoverflow.com/questions/14475171/jmsserializerbundle-complex- generated-value –

Odpowiedz

3

Sam pakiet Serializera może nie wystarczyć dla tej sytuacji, ponieważ dotyczy tylko serializacji i deserializacji, a nie bardziej złożonych zadań semantycznych.

Proponuję przejrzeć FSCHateoasBundle, aby zaimplementować ładny format hipermedialny dla interfejsu API.