10/02/2018 - SYMFONY
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 the bundle by running $ composer require jms/serializer-bundle
command and enable it in AppKernel.php by adding new JMS\SerializerBundle\JMSSerializerBundle(),
into it.
You can add any key-value pair under random
property.
POST /customers
Content-Type: application/json
{
"name": "inanzzz",
"dob": "01/01/2001",
"random": {
"car": "Aston Martin",
"type": "DB9",
"team": "Arsenal"
}
}
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>
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"
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;
}
CustomerBundle\Model\Customer\Create Object
(
[name] => inanzzz
[dob] => 01/01/2001
[random] => Array
(
[car] => Aston Martin
[type] => DB9
[team] => Arsenal
)
)