Serializer Component with Symfony
Tags: symfony, serializer, php, beginners
Published: 2019-02-24 23:31:49

---
title: Serializer Component with Symfony
published: true
description: I am going to introduce Serializer Component using in the Symfony.
tags: #symfony #serializer #php #beginners
---

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](https://thepracticaldev.s3.amazonaws.com/i/7jiy3jun1y7j659c2kqe.png "")

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

```bash
composer require symfony/serializer -vvv
```

After that, I added my configuration lines in `framework.yaml`file.

```yaml
framework:
    serializer:
        enabled: true
        enable_annotations: true
```

I've adjusted the configuration. Now, I wrote my first code.

```php
<?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.

![alt text](https://thepracticaldev.s3.amazonaws.com/i/awsdd90l63du1ulyvei1.png "")

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

```php 
$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.

![alt text](https://thepracticaldev.s3.amazonaws.com/i/mvece4exsnmtygcxe8fa.png "")

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

```php 
$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.

![alt text](https://thepracticaldev.s3.amazonaws.com/i/799rn1szfa3u125b6923.png "")

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

![alt text](https://thepracticaldev.s3.amazonaws.com/i/zn2g920kmobu64rehyf1.png "")

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.


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

![alt text](https://thepracticaldev.s3.amazonaws.com/i/kreo2ec6qjgr1brc7zi8.png "")

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