Magento 2 Experten — Hyvä Theme, Tailwind CSS & SEO aus einer Hand ›

Serialization Groups for Reading

Serialization Groups for Reading

~15 Min. Lesezeit Zuletzt aktualisiert am August 8, 2026

So far, ALL properties of an entity appear in the JSON – normalizationContext combined with serialization groups allows restricting that ON PURPOSE.

The #[Groups] attribute on properties

api/src/Entity/Project.php
use ApiPlatform\Metadata\ApiResource;
use Symfony\Component\Serializer\Attribute\Groups;

#[ApiResource(
    normalizationContext: ['groups' => ['project:read']]
)]
#[ORM\Entity(repositoryClass: ProjectRepository::class)]
class Project
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    #[Groups(['project:read'])]
    private ?int $id = null;

    #[ORM\Column(length: 255)]
    #[Assert\NotBlank]
    #[Groups(['project:read'])]
    private string $name = '';

    #[ORM\Column(type: 'text', nullable: true)]
    #[Groups(['project:read'])]
    private ?string $description = null;

    #[ORM\Column]
    #[Groups(['project:read'])]
    private \DateTimeImmutable $createdAt;

    // priority WITHOUT #[Groups] - it therefore no longer appears in the JSON
    #[ORM\Column]
    #[Assert\Range(min: 1, max: 5)]
    private int $priority = 3;

    // ... getters/setters unchanged
}

normalizationContext controls READING (GET responses) – ONLY properties with #[Groups(['project:read'])] end up in the response JSON.

Checking the result

curl -k https://localhost/api/projects/1
{
  "@context": "/api/contexts/Project",
  "@id": "/api/projects/1",
  "@type": "Project",
  "id": 1,
  "name": "Website Relaunch",
  "description": "Complete redesign",
  "createdAt": "2026-08-06T12:00:00+00:00"
}

Achtung: priority is COMPLETELY missing from the response, EVEN THOUGH the field exists in the database and has a value – serialization groups don't filter individual values, they filter WHOLE properties OUT of the response.

Applying groups to multiple resources

The EXACT same attribute is also used on Tag#[Groups(['tag:read'])] on id and name, with its OWN, independent group name. Group names are FREELY chosen, there is NO technical requirement for {resource}:{purpose} beyond GOOD readability.

Tipp: If normalizationContext is COMPLETELY missing (as in chapters 9-22 so far), NO group filtering applies – ALL properties appear automatically. Switching to explicit groups is a DELIBERATE step, not automatic behavior.