@@ -1545,6 +1545,254 @@ like:
1545
1545
PropertyNormalizer::NORMALIZE_VISIBILITY => PropertyNormalizer::NORMALIZE_PUBLIC | PropertyNormalizer::NORMALIZE_PROTECTED,
1546
1546
]);
1547
1547
1548
+ Named Serializers
1549
+ -----------------
1550
+
1551
+ .. versionadded :: 7.2
1552
+
1553
+ Named serializers were introduced in Symfony 7.2.
1554
+
1555
+ Sometimes, you may need multiple configurations for the serializer, such as
1556
+ different default contexts, name converters, or sets of normalizers and encoders,
1557
+ depending on the use case. For example, when your application communicates with
1558
+ multiple APIs, each of which follows its own set of serialization rules.
1559
+
1560
+ You can achieve this by configuring multiple serializer instances using
1561
+ the ``named_serializers `` option:
1562
+
1563
+ .. configuration-block ::
1564
+
1565
+ .. code-block :: yaml
1566
+
1567
+ # config/packages/serializer.yaml
1568
+ framework :
1569
+ serializer :
1570
+ named_serializers :
1571
+ api_client1 :
1572
+ name_converter : ' serializer.name_converter.camel_case_to_snake_case'
1573
+ default_context :
1574
+ enable_max_depth : true
1575
+ api_client2 :
1576
+ default_context :
1577
+ enable_max_depth : false
1578
+
1579
+ .. code-block :: xml
1580
+
1581
+ <!-- config/packages/serializer.xml -->
1582
+ <?xml version =" 1.0" encoding =" UTF-8" ?>
1583
+ <container xmlns =" http://symfony.com/schema/dic/services"
1584
+ xmlns : xsi =" http://www.w3.org/2001/XMLSchema-instance"
1585
+ xmlns : framework =" http://symfony.com/schema/dic/symfony"
1586
+ xsi : schemaLocation =" http://symfony.com/schema/dic/services
1587
+ https://symfony.com/schema/dic/services/services-1.0.xsd
1588
+ http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd" >
1589
+
1590
+ <framework : config >
1591
+ <framework : serializer >
1592
+
1593
+ <framework : named-serializer
1594
+ name =" api_client1"
1595
+ name-converter =" serializer.name_converter.camel_case_to_snake_case"
1596
+ >
1597
+ <framework : default-context >
1598
+ <framework : enable_max_depth >true</framework : enable_max_depth >
1599
+ </framework : default-context >
1600
+ </framework : named-serializer >
1601
+
1602
+ <framework : named-serializer name =" api_client2" >
1603
+ <framework : default-context >
1604
+ <framework : enable_max_depth >false</framework : enable_max_depth >
1605
+ </framework : default-context >
1606
+ </framework : named-serializer >
1607
+
1608
+ </framework : serializer >
1609
+ </framework : config >
1610
+ </container >
1611
+
1612
+ .. code-block :: php
1613
+
1614
+ // config/packages/serializer.php
1615
+ use Symfony\Config\FrameworkConfig;
1616
+
1617
+ return static function (FrameworkConfig $framework): void {
1618
+ $framework->serializer()
1619
+ ->namedSerializer('api_client1')
1620
+ ->nameConverter('serializer.name_converter.camel_case_to_snake_case')
1621
+ ->defaultContext([
1622
+ 'enable_max_depth' => true,
1623
+ ])
1624
+ ;
1625
+ $framework->serializer()
1626
+ ->namedSerializer('api_client2')
1627
+ ->defaultContext([
1628
+ 'enable_max_depth' => false,
1629
+ ])
1630
+ ;
1631
+ };
1632
+
1633
+ You can inject these different serializer instances
1634
+ using :ref: `named aliases <autowiring-multiple-implementations-same-type >`::
1635
+
1636
+ namespace App\Controller;
1637
+
1638
+ // ...
1639
+ use Symfony\Component\DependencyInjection\Attribute\Target;
1640
+
1641
+ class PersonController extends AbstractController
1642
+ {
1643
+ public function index(
1644
+ SerializerInterface $serializer, // default serializer
1645
+ SerializerInterface $apiClient1Serializer, // api_client1 serializer
1646
+ #[Target('apiClient2.serializer')] // api_client2 serializer
1647
+ SerializerInterface $customName,
1648
+ ) {
1649
+ // ...
1650
+ }
1651
+ }
1652
+
1653
+ By default, named serializers use the built-in set of normalizers and encoders,
1654
+ just like the main serializer service. However, you can customize them by
1655
+ registering additional normalizers or encoders for a specific named serializer.
1656
+ To do that, add a ``serializer `` attribute to
1657
+ the :ref: `serializer.normalizer <reference-dic-tags-serializer-normalizer >`
1658
+ or :ref: `serializer.encoder <reference-dic-tags-serializer-encoder >` tags:
1659
+
1660
+ .. configuration-block ::
1661
+
1662
+ .. code-block :: yaml
1663
+
1664
+ # config/services.yaml
1665
+ services :
1666
+ # ...
1667
+
1668
+ Symfony\Component\Serializer\Normalizer\CustomNormalizer :
1669
+ # prevent this normalizer from being automatically added to the default serializer
1670
+ autoconfigure : false
1671
+ tags :
1672
+ # add this normalizer only to a specific named serializer
1673
+ - serializer.normalizer : { serializer: 'api_client1' }
1674
+ # add this normalizer to several named serializers
1675
+ - serializer.normalizer : { serializer: [ 'api_client1', 'api_client2' ] }
1676
+ # add this normalizer to all serializers, including the default one
1677
+ - serializer.normalizer : { serializer: '*' }
1678
+
1679
+ .. code-block :: xml
1680
+
1681
+ <!-- config/services.xml -->
1682
+ <?xml version =" 1.0" encoding =" UTF-8" ?>
1683
+ <container xmlns =" http://symfony.com/schema/dic/services"
1684
+ xmlns : xsi =" http://www.w3.org/2001/XMLSchema-instance"
1685
+ xsi : schemaLocation =" http://symfony.com/schema/dic/services
1686
+ https://symfony.com/schema/dic/services/services-1.0.xsd" >
1687
+
1688
+ <services >
1689
+ <!-- ... -->
1690
+
1691
+ <!-- prevent this normalizer from being automatically added to the default serializer -->
1692
+ <service
1693
+ id =" Symfony\Component\Serializer\Normalizer\CustomNormalizer"
1694
+ autoconfigure =" false"
1695
+ >
1696
+ <!-- add this normalizer only to a specific named serializer -->
1697
+ <tag name =" serializer.normalizer" serializer =" api_client1" />
1698
+
1699
+ <!-- add this normalizer to several named serializers -->
1700
+ <tag name =" serializer.normalizer" serializer =" api_client1" />
1701
+ <tag name =" serializer.normalizer" serializer =" api_client2" />
1702
+
1703
+ <!-- add this normalizer to all serializers, including the default one -->
1704
+ <tag name =" serializer.normalizer" serializer =" *" />
1705
+ </service >
1706
+ </services >
1707
+ </container >
1708
+
1709
+ .. code-block :: php
1710
+
1711
+ // config/services.php
1712
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
1713
+
1714
+ use Symfony\Component\Serializer\Normalizer\CustomNormalizer;
1715
+
1716
+ return function(ContainerConfigurator $container) {
1717
+ // ...
1718
+
1719
+ $services->set(CustomNormalizer::class)
1720
+ // prevent this normalizer from being automatically added to the default serializer
1721
+ ->autoconfigure(false)
1722
+
1723
+ // add this normalizer only to a specific named serializer
1724
+ ->tag('serializer.normalizer', ['serializer' => 'api_client1'])
1725
+ // add this normalizer to several named serializers
1726
+ ->tag('serializer.normalizer', ['serializer' => ['api_client1', 'api_client2']])
1727
+ // add this normalizer to all serializers, including the default one
1728
+ ->tag('serializer.normalizer', ['serializer' => '*'])
1729
+ ;
1730
+ };
1731
+
1732
+ When the ``serializer `` attribute is not set, the service is registered only with
1733
+ the default serializer.
1734
+
1735
+ Each normalizer or encoder used in a named serializer is tagged with a
1736
+ ``serializer.normalizer.<name> `` or ``serializer.encoder.<name> `` tag.
1737
+ You can inspect their priorities using the following command:
1738
+
1739
+ .. code-block :: terminal
1740
+
1741
+ $ php bin/console debug:container --tag serializer.<normalizer|encoder>.<name>
1742
+
1743
+ Additionally, you can exclude the default set of normalizers and encoders from a
1744
+ named serializer by setting the ``include_built_in_normalizers `` and
1745
+ ``include_built_in_encoders `` options to ``false ``:
1746
+
1747
+ .. configuration-block ::
1748
+
1749
+ .. code-block :: yaml
1750
+
1751
+ # config/packages/serializer.yaml
1752
+ framework :
1753
+ serializer :
1754
+ named_serializers :
1755
+ api_client1 :
1756
+ include_built_in_normalizers : false
1757
+ include_built_in_encoders : true
1758
+
1759
+ .. code-block :: xml
1760
+
1761
+ <!-- config/packages/serializer.xml -->
1762
+ <?xml version =" 1.0" encoding =" UTF-8" ?>
1763
+ <container xmlns =" http://symfony.com/schema/dic/services"
1764
+ xmlns : xsi =" http://www.w3.org/2001/XMLSchema-instance"
1765
+ xmlns : framework =" http://symfony.com/schema/dic/symfony"
1766
+ xsi : schemaLocation =" http://symfony.com/schema/dic/services
1767
+ https://symfony.com/schema/dic/services/services-1.0.xsd
1768
+ http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd" >
1769
+
1770
+ <framework : config >
1771
+ <framework : serializer >
1772
+
1773
+ <framework : named-serializer
1774
+ name =" api_client1"
1775
+ include-built-in-normalizers =" false"
1776
+ include-built-in-encoders =" true"
1777
+ />
1778
+
1779
+ </framework : serializer >
1780
+ </framework : config >
1781
+ </container >
1782
+
1783
+ .. code-block :: php
1784
+
1785
+ // config/packages/serializer.php
1786
+ use Symfony\Config\FrameworkConfig;
1787
+
1788
+ return static function (FrameworkConfig $framework): void {
1789
+ $framework->serializer()
1790
+ ->namedSerializer('api_client1')
1791
+ ->includeBuiltInNormalizers(false)
1792
+ ->includeBuiltInEncoders(true)
1793
+ ;
1794
+ };
1795
+
1548
1796
Debugging the Serializer
1549
1797
------------------------
1550
1798
0 commit comments