Serializer Component with Symfony

_mertsimsek

Mert Simsek

Posted on February 24, 2019

Serializer Component with Symfony

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.

alt text

-- 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
Enter fullscreen mode Exit fullscreen mode

After that, I added my configuration lines in framework.yamlfile.

framework:
    serializer:
        enabled: true
        enable_annotations: true
Enter fullscreen mode Exit fullscreen mode

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

    }
}
Enter fullscreen mode Exit fullscreen mode

I implement the serializer interface and I convert the claimed format. The response is going to be like this.

alt text

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

}
Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

How my response appears? Here you are.

alt text

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

Enter fullscreen mode Exit fullscreen mode

Immediately, we make sure the result.

alt text

Or csv... For this thime, of course, I converted to xml to csv.

alt text

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
Enter fullscreen mode Exit fullscreen mode

From now on, the created at property is going to be snake_case formatted.

alt text

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.

💖 💪 🙅 🚩
_mertsimsek
Mert Simsek

Posted on February 24, 2019

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

Serializer Component with Symfony
symfony Serializer Component with Symfony

February 24, 2019