When it comes to mapping request data to model classes, you need certain properties in request. Sometimes request might have unexpected properties in them and you want to map them too. This is hard because you would never know the property names. This example handles it with JMSSerializerBundle. There is one rule so unexpected properties should present in a known property.


Install


Install the bundle by running $ composer require jms/serializer-bundle command and enable it in AppKernel.php by adding new JMS\SerializerBundle\JMSSerializerBundle(), into it.


Request


You can add any key-value pair under random property.


JSON


POST /customers
Content-Type: application/json

{
"name": "inanzzz",
"dob": "01/01/2001",
"random": {
"car": "Aston Martin",
"type": "DB9",
"team": "Arsenal"
}
}

XML


POST /customers
Content-Type: application/xml

<?xml version="1.0" encoding="UTF-8"?>
<customer>
<name>inanzzz</name>
<dob>01/01/2001</dob>
<random>
<car>Aston Martin</car>
<model>DB9</model>
<team>Arsenal</team>
</random>
</customer>

CustomerController


namespace CustomerBundle\Controller;

use CustomerBundle\Model\Customer\Create;
use JMS\Serializer\SerializerInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Request;

/**
* @Route("", service="customer.controller.customer")
*/
class CustomerController
{
private $serializer;

public function __construct(
SerializerInterface $serializer
) {
$this->serializer = $serializer;
}

/**
* @param Request $request
*
* @Method({"POST"})
* @Route("")
*/
public function createAction(Request $request)
{
// You should validate the $request first

$create = $this->serializer->deserialize(
$request->getContent(),
Create::class,
$this->getFormat($request->headers->get('content_type'))
);

print_r($create);
}

private function getFormat($contentType)
{
// You should validate the $contentType first

return array_search($contentType, ['json' => 'application/json', 'xml' => 'application/xml']);
}
}

services:
customer.controller.customer:
class: CustomerBundle\Controller\CustomerController
arguments:
- "@jms_serializer"

Model


namespace CustomerBundle\Model\Customer;

use JMS\Serializer\Annotation as Serializer;

/**
* @Serializer\XmlRoot("customer")
*/
class Create
{
/**
* @Serializer\Type("string")
*/
public $name;

/**
* @Serializer\Type("string")
*/
public $dob;

/**
* @Serializer\Type("array<string, string>")
* @Serializer\XmlKeyValuePairs
*/
public $random;
}

Result


CustomerBundle\Model\Customer\Create Object
(
[name] => inanzzz
[dob] => 01/01/2001
[random] => Array
(
[car] => Aston Martin
[type] => DB9
[team] => Arsenal
)
)