sajad torkamani

In a nutshell

API Platform’s serialization layer builds on top of the Symfony Serializer component. Refer to the following posts for more on the Symfony Serializer component:

Here’s a visual illustration of how serialization works in API platform:

Serialization in API Platform

Serialization is a two-step process:

  1. A PHP object is first normalized into a PHP array.
  2. The PHP array is encoded into something like JSON or XML.

Out of the box, API Platform uses the ObjectNormalizer to normalize your entities into arrays, using your entities’ getters and setters. For example, when it tries to normalize the following entity:

<?php

[ApiResource()]
class User {
   private int $id;

   private string $name;
  
   public getId(): int {
      return $this->id;
   }
  
   public getId(): int {
      return $this->id;
   }
}

into JSON like this:

{
  "id": "<some-id>"
  "name": "<some-name>"
}

For every JSON property, it will check the entity for a getter method (i.e., id -> getId(), name -> getName(), etc).

What to use serialization groups for?

Use serialization groups to control responses

You can use serialization groups to control what fields are returned in outgoing responses. For example, you might specify a read normalization context like so:

<?php
// api/src/Entity/Book.php

namespace App\Entity;

use ApiPlatform\Core\Annotation\ApiResource;
use Symfony\Component\Serializer\Annotation\Groups;

#[ApiResource(
    normalizationContext: ['groups' => ['read']],
    denormalizationContext: ['groups' => ['write']],
)]
class Book
{
    #[Groups(["read", "write"])]
    public $name;

    #[Groups("write")]
    public $author;

    // ...
}

The normalizationContext: ['groups' => ['read']] annotation tells API Platform that only the properties that are part of the read group should be exposed in responses relating to this entity.

In the above example, this means that a request like GET /v1/books/123 will include the $name property but not $author.

API Platform will use this information when generating Open API documentation so that your API users will know what data they can expect from the response.

Use serialization groups to specify which properties can be sent in requests

The denormalizationContext: ['groups' => ['write']] annotation tells API Platform that only the properties that have the write group will be used to reconstruct the entity from the decoded array.

In the above example, this means that a POST /v1/books request will accept the $name property but not $author.

API platform will use this information when generating Open API documentation so that your API users will know what data they can send.

You can specify serialization groups at the operation level

Normalization groups can also be set at the operation level. Operation-level groups take precedence over those set at the resource level.

<?php
// api/src/Entity/Book.php

namespace App\Entity;

use ApiPlatform\Core\Annotation\ApiResource;
use Symfony\Component\Serializer\Annotation\Groups;

#[ApiResource(
    normalizationContext: ['groups' => ['get']],
    itemOperations: [
        'get',
        'put' => [
            'normalization_context' => ['groups' => ['put']],
        ],
    ],
)]
class Book
{
    #[Groups(["get", "put"])]
    public $name;

    #[Groups("get")]
    public $author;

    // ...
}

Key terms

TermDescription
SerializationThe complete process of translating a data structure (e.g., Doctrine entity) into a format (e.g., JSON) that can be sent over the network.
DeserializationThe complete process of reconstructing a data structure (e.g., Doctrine entity) from a data string (e.g., JSON) sent over the network.
NormalizationThe process of converting a PHP object into a PHP array.
DenormalizationThe process of converting a PHP array into a PHP object.
EncodingThe process of translating a PHP array into a data string (e.g., JSON or XML).
DecodingThe process of reconstructing a PHP array from a data string (e.g., JSON or XML).

Sources