How to Create your Custom Normalizer

The Serializer component uses normalizers to transform any data into an array. The component provides several built-in normalizers but you may need to create your own normalizer to transform an unsupported data structure.

Serializer コンポーネントはノーマライザーを使用して、データを配列に変換します。このコンポーネントにはいくつかの組み込みノーマライザーが用意されていますが、サポートされていないデータ構造を変換するには、独自のノーマライザーを作成する必要がある場合があります。

Creating a New Normalizer

Imagine you want add, modify, or remove some properties during the serialization process. For that you'll have to create your own normalizer. But it's usually preferable to let Symfony normalize the object, then hook into the normalization to customize the normalized data. To do that, leverage the ObjectNormalizer:

シリアル化プロセス中にいくつかのプロパティを追加、変更、または削除するとします。そのためには、独自のノーマライザーを作成する必要があります。しかし通常は、Symfony にオブジェクトを正規化させてから、正規化にフックして正規化されたデータをカスタマイズすることをお勧めします。これを行うには、ObjectNormalizer を活用します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// src/Serializer/TopicNormalizer.php
namespace App\Serializer;

use App\Entity\Topic;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;

class TopicNormalizer implements NormalizerInterface
{
    private $router;
    private $normalizer;

    public function __construct(UrlGeneratorInterface $router, ObjectNormalizer $normalizer)
    {
        $this->router = $router;
        $this->normalizer = $normalizer;
    }

    public function normalize($topic, string $format = null, array $context = [])
    {
        $data = $this->normalizer->normalize($topic, $format, $context);

        // Here, add, edit, or delete some data:
        $data['href']['self'] = $this->router->generate('topic_show', [
            'id' => $topic->getId(),
        ], UrlGeneratorInterface::ABSOLUTE_URL);

        return $data;
    }

    public function supportsNormalization($data, string $format = null, array $context = [])
    {
        return $data instanceof Topic;
    }
}

Registering it in your Application

Before using this normalizer in a Symfony application it must be registered as a service and tagged with serializer.normalizer. If you're using the default services.yaml configuration, this is done automatically!

Symfony アプリケーションでこのノーマライザーを使用する前に、サービスとして登録し、serializer.normalizer でタグ付けする必要があります。デフォルトの services.yaml 構成を使用している場合、これは自動的に行われます!

Performance

To figure which normalizer (or denormalizer) must be used to handle an object, the Serializer class will call the supportsNormalization() (or supportsDenormalization()) of all registered normalizers (or denormalizers) in a loop.

オブジェクトを処理するためにどのノーマライザー (またはデノーマライザー) を使用する必要があるかを判断するために、Serializer クラスは、登録されているすべてのノーマライザー (またはデノーマライザー) の supportsNormalization() (または supportsDenormalization()) をループで呼び出します。

The result of these methods can vary depending on the object to serialize, the format and the context. That's why the result is not cached by default and can result in a significant performance bottleneck.

これらのメソッドの結果は、シリアル化するオブジェクト、形式、およびコンテキストによって異なります。そのため、デフォルトでは結果がキャッシュされず、重大なパフォーマンスのボトルネックになる可能性があります。

However, most normalizers (and denormalizers) always return the same result when the object's type and the format are the same, so the result can be cached. To do so, make those normalizers (and denormalizers) implement the CacheableSupportsMethodInterface and return true when hasCacheableSupportsMethod() is called.

ただし、ほとんどのノーマライザー (およびデノーマライザー) は、オブジェクトの型と形式が同じ場合は常に同じ結果を返すため、結果をキャッシュできます。そうするには、ノーマライザー (およびデノーマライザー) に CacheableSupportsMethodInterface を実装させ、hasCacheableSupportsMethod() が呼び出されたときに true を返すようにします。

Note

ノート

All built-in normalizers and denormalizers as well the ones included in API Platform natively implement this interface.

すべての組み込みのノーマライザーとデノーマライザー、および API プラットフォームに含まれるものは、このインターフェイスをネイティブに実装します。