HypeMC
Contributed by HypeMC in #56823

In Symfony 7.2, the Serializer component allows configuring multiple serializer instances with different default contexts, name converters, and sets of normalizers and encoders. This is useful, for example, when your application communicates with multiple APIs, each using different rules.

First, use the new named_serializers option to define the different serializers and their contexts:

1
2
3
4
5
6
7
8
9
10
# config/packages/serializer.yaml
serializer:
    named_serializers:
        api_client1:
            name_converter: 'serializer.name_converter.camel_case_to_snake_case'
            default_context:
                enable_max_depth: true
        api_client2:
            default_context:
                enable_max_depth: false

Now you can inject the different serializers using named aliases including the Target attribute:

1
2
3
4
5
6
7
8
9
10
11
12
class HomeController extends AbstractController
{
    #[Route('/', name: 'app_home')]
    public function index(
        SerializerInterface $serializer,           // Default serializer
        SerializerInterface $apiClient1Serializer, // api_client1 serializer
        #[Target('apiClient2.serializer')]         // api_client2 serializer
        SerializerInterface $someName,
    ) {
        // ...
    }
}

If you define custom normalizers, you can apply them only to certain serializers thanks to the serializer tag attribute (if you don't set this attribute, the normalizer will be applied only to the default serializer):

1
2
3
4
5
6
7
8
9
10
get_set_method_normalizer:
    class: Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer
    autoconfigure: false # this is needed so it's not included in the default serializer
    tags:
        # single serializer
        - serializer.normalizer: { serializer: 'api_client1' }
        # or multiple ones
        - serializer.normalizer: { serializer: [ 'api_client1', 'api_client2' ] }
        # use * to include the service in all serializers, including the default one
        - serializer.normalizer: { serializer: '*' }

Lastly, since Symfony comes with some built-in normalizers and encoders, there are new options to exclude those in case you don't want to use them:

1
2
3
4
5
6
serializer:
    named_serializers:
        api_client1:
            include_built_in_normalizers: false
            include_built_in_encoders: true
            # ...
Published in #Living on the edge