Serializer Component with Symfony
Mert Simsek
Posted on February 24, 2019
This post leads to use Serialization in our projects. But What's the serialization and who needs that? We will answer these needful questions. They are help us to understand that obviously. Well, let's start.
What's the serialization?
For developers; It's transforming an object to a formatted string. We would have textual, JSON, XML. On the other hand, binary formats. Generally, we develop REST Apis commonly. Whereas, different programming languages and different machines should stay in touch each other by our REST Apis endpoints. At this point, serialization truly works for us.
Who needs serialization?
As a developer, we are able to refer this way. Initially, we send or receive data when we develop a REST Api. It should be strict format to manage all of communication. The most common use case is queue systems. We figure out queue systems with serialization. Other thing might be testing. We are able to detect some changes. Plus, If we want to store data in database instead of having columns with fields. We can have only one field for all data. If I need to give some instances, they might be like Redis, Elasticsearch.
How it works?
Here is the architecture of how it works.
-- Normalizers --
First of all, there is an object format. Normalizers are obviously classes that to convert objects to an array. Array structure is easily understand and manipulate.
-- Encoders --
These classes are convert from array to the claimed format. Or, claimed formatted to array.
Well, from now on we are able to start writing some codes. I am going to give some tips about that. For this, I installed the component.
composer require symfony/serializer -vvv
After that, I added my configuration lines in framework.yaml
file.
framework:
serializer:
enabled: true
enable_annotations: true
I've adjusted the configuration. Now, I wrote my first code.
<?php
namespace App\Controller;
use App\Entity\User;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Serializer\SerializerInterface;
class UserController extends AbstractController
{
/**
* @Route("/user", name="user")
* @param SerializerInterface $serializer
* @return JsonResponse
*/
public function index(SerializerInterface $serializer)
{
$user = new User();
$user->setFullname('Mert Simsek')
->setCity('İstanbul')
->setEmail('mertsmsk0@gmail.com')
->setPhone('+90-000-000-00-00')
->setCreatedAt(new \DateTime('2019-02-25 00:00:00'));
$serializedUser = $serializer->serialize($user,'json');
return JsonResponse::fromJsonString($serializedUser);
}
}
I implement the serializer interface and I convert the claimed format. The response is going to be like this.
At the moment, I would like to highlight some features. First of all is groups
. Picture that, you've all of these columns; fullname, phone, city etc. But you don't want to provide all of them. At this point, "groups" helps us. How? Like this. You write "groups" line each propery of the entity as below.
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation\Groups;
/**
* @ORM\Entity(repositoryClass="App\Repository\UserRepository")
*/
class User
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
* @Groups({"phone","web"})
*/
private $id;
/**
* @ORM\Column(type="string", length=255)
* @Groups({"phone","web"})
*/
private $fullname;
/**
* @ORM\Column(type="string", length=255)
* @Groups({"phone","web"})
*/
private $city;
/**
* @ORM\Column(type="string", length=255)
* @Groups({"phone"})
*/
private $phone;
/**
* @ORM\Column(type="string", length=255)
* @Groups({"phone","web"})
*/
private $email;
/**
* @ORM\Column(type="datetime")
* @Groups({"phone","web"})
*/
private $createdAt;
// at this point, there are getters and setters...
}
Now, we can serialize with this "groups" defining. As you see, If I serialize with "web" group, the phone property is not going to appear us. Because, the phone property is appearing for only "phone group". Let's see.
$user = new User();
$user->setFullname('Mert Simsek')
->setCity('İstanbul')
->setEmail('mertsmsk0@gmail.com')
->setPhone('+90-000-000-00-00')
->setCreatedAt(new \DateTime('2019-02-25 00:00:00'));
$serializedUser = $serializer->serialize($user,'json', ['groups' => ['web']]);
return JsonResponse::fromJsonString($serializedUser);
How my response appears? Here you are.
As you see, anymore we cannot see the phone property. Now let's check it out the other formats. For instance, xml? I changed the format from json to xml.
$user = new User();
$user->setFullname('Mert Simsek')
->setCity('İstanbul')
->setEmail('mertsmsk0@gmail.com')
->setPhone('+90-000-000-00-00')
->setCreatedAt(new \DateTime('2019-02-25 00:00:00'));
$serializedUser = $serializer->serialize($user,'xml', ['groups' => ['web']]);
return JsonResponse::fromJsonString($serializedUser);
Immediately, we make sure the result.
Or csv... For this thime, of course, I converted to xml to csv.
I would like to mention about other one feature. It's Name Convertor. If we need to change from camelCase to snake_case, we just add this line into configuration.
framework:
serializer:
enabled: true
enable_annotations: true
name_converter: serializer.name_converter.camel_case_to_snake_case
From now on, the created at
property is going to be snake_case formatted.
To Sum Up
I would like to thank all of you for reading till this point. Serializer Component has plenty of feature. Specially, when you develop the REST Apis, it truly helps you.
Posted on February 24, 2019
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.