Skip to content

Commit bf8e300

Browse files
committed
[Serializer] Document named serializers
1 parent 8801059 commit bf8e300

File tree

1 file changed

+249
-0
lines changed

1 file changed

+249
-0
lines changed

serializer.rst

Lines changed: 249 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1472,6 +1472,255 @@ like:
14721472
PropertyNormalizer::NORMALIZE_VISIBILITY => PropertyNormalizer::NORMALIZE_PUBLIC | PropertyNormalizer::NORMALIZE_PROTECTED,
14731473
]);
14741474

1475+
Named Serializers
1476+
-----------------
1477+
1478+
.. versionadded:: 7.2
1479+
1480+
Named serializers were introduced in Symfony 7.2.
1481+
1482+
Sometimes, you may need multiple configurations for the serializer, such
1483+
as different default contexts, name converters, or sets of normalizers and
1484+
encoders, depending on the use case. For example, when your application
1485+
communicates with multiple APIs, each with its own set of rules.
1486+
1487+
This can be achieved by configuring multiple instances of the serializer
1488+
using the ``named_serializers`` option:
1489+
1490+
.. configuration-block::
1491+
1492+
.. code-block:: yaml
1493+
1494+
# config/packages/serializer.yaml
1495+
framework:
1496+
serializer:
1497+
named_serializers:
1498+
api_client1:
1499+
name_converter: 'serializer.name_converter.camel_case_to_snake_case'
1500+
default_context:
1501+
enable_max_depth: true
1502+
api_client2:
1503+
default_context:
1504+
enable_max_depth: false
1505+
1506+
.. code-block:: xml
1507+
1508+
<!-- config/packages/serializer.xml -->
1509+
<?xml version="1.0" encoding="UTF-8" ?>
1510+
<container xmlns="http://symfony.com/schema/dic/services"
1511+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1512+
xmlns:framework="http://symfony.com/schema/dic/symfony"
1513+
xsi:schemaLocation="http://symfony.com/schema/dic/services
1514+
https://symfony.com/schema/dic/services/services-1.0.xsd
1515+
http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
1516+
1517+
<framework:config>
1518+
<framework:serializer>
1519+
1520+
<framework:named-serializer
1521+
name="api_client1"
1522+
name-converter="serializer.name_converter.camel_case_to_snake_case"
1523+
>
1524+
<framework:default-context>
1525+
<framework:enable_max_depth>true</framework:enable_max_depth>
1526+
</framework:default-context>
1527+
</framework:named-serializer>
1528+
1529+
<framework:named-serializer name="api_client2">
1530+
<framework:default-context>
1531+
<framework:enable_max_depth>false</framework:enable_max_depth>
1532+
</framework:default-context>
1533+
</framework:named-serializer>
1534+
1535+
</framework:serializer>
1536+
</framework:config>
1537+
</container>
1538+
1539+
.. code-block:: php
1540+
1541+
// config/packages/serializer.php
1542+
use Symfony\Config\FrameworkConfig;
1543+
1544+
return static function (FrameworkConfig $framework): void {
1545+
$framework->serializer()
1546+
->namedSerializer('api_client1')
1547+
->nameConverter('serializer.name_converter.camel_case_to_snake_case')
1548+
->defaultContext([
1549+
'enable_max_depth' => true,
1550+
])
1551+
;
1552+
$framework->serializer()
1553+
->namedSerializer('api_client2')
1554+
->defaultContext([
1555+
'enable_max_depth' => false,
1556+
])
1557+
;
1558+
};
1559+
1560+
You can inject these different serializer instances
1561+
using :ref:`named aliases <autowiring-multiple-implementations-same-type>`::
1562+
1563+
namespace App\Controller;
1564+
1565+
// ...
1566+
use Symfony\Component\DependencyInjection\Attribute\Target;
1567+
1568+
class PersonController extends AbstractController
1569+
{
1570+
public function index(
1571+
SerializerInterface $serializer, // Default serializer
1572+
SerializerInterface $apiClient1Serializer, // api_client1 serializer
1573+
#[Target('apiClient2.serializer')] // api_client2 serializer
1574+
SerializerInterface $customName,
1575+
) {
1576+
// ...
1577+
}
1578+
}
1579+
1580+
Named serializers are configured with the default set of normalizers and encoders.
1581+
1582+
You can register additional normalizers and encoders with a specific named
1583+
serializer by adding a ``serializer`` attribute to
1584+
the :ref:`serializer.normalizer <reference-dic-tags-serializer-normalizer>`
1585+
or :ref:`serializer.encoder <reference-dic-tags-serializer-encoder>` tags:
1586+
1587+
.. configuration-block::
1588+
1589+
.. code-block:: yaml
1590+
1591+
# config/services.yaml
1592+
services:
1593+
# ...
1594+
1595+
Symfony\Component\Serializer\Normalizer\CustomNormalizer:
1596+
# Prevent this normalizer from automatically being included in the default serializer
1597+
autoconfigure: false
1598+
tags:
1599+
# Include this normalizer in a single serializer
1600+
- serializer.normalizer: { serializer: 'api_client1' }
1601+
# Include this normalizer in multiple serializers
1602+
- serializer.normalizer: { serializer: [ 'api_client1', 'api_client2' ] }
1603+
# Include this normalizer in all serializers (including the default one)
1604+
- serializer.normalizer: { serializer: '*' }
1605+
1606+
.. code-block:: xml
1607+
1608+
<!-- config/services.xml -->
1609+
<?xml version="1.0" encoding="UTF-8" ?>
1610+
<container xmlns="http://symfony.com/schema/dic/services"
1611+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1612+
xsi:schemaLocation="http://symfony.com/schema/dic/services
1613+
https://symfony.com/schema/dic/services/services-1.0.xsd">
1614+
1615+
<services>
1616+
<!-- ... -->
1617+
1618+
<!-- Disable autoconfigure to prevent this normalizer from automatically -->
1619+
<!-- being included in the default serializer -->
1620+
<service
1621+
id="Symfony\Component\Serializer\Normalizer\CustomNormalizer"
1622+
autoconfigure="false"
1623+
>
1624+
<!-- Include this normalizer in a single serializer -->
1625+
<tag name="serializer.normalizer" serializer="api_client1"/>
1626+
1627+
<!-- Include this normalizer in multiple serializers -->
1628+
<tag name="serializer.normalizer" serializer="api1"/>
1629+
<tag name="serializer.normalizer" serializer="api2"/>
1630+
1631+
<!-- Include this normalizer in all serializers (including the default one) -->
1632+
<tag name="serializer.normalizer" serializer="*"/>
1633+
</service>
1634+
</services>
1635+
</container>
1636+
1637+
.. code-block:: php
1638+
1639+
// config/services.php
1640+
namespace Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
1641+
1642+
use Symfony\Component\Serializer\Normalizer\CustomNormalizer;
1643+
1644+
return function(ContainerConfigurator $container) {
1645+
// ...
1646+
1647+
$services->set(CustomNormalizer::class)
1648+
// Prevent this normalizer from automatically being included in the default serializer
1649+
->autoconfigure(false)
1650+
1651+
// Include this normalizer in a single serializer
1652+
->tag('serializer.normalizer', ['serializer' => 'api_client1'])
1653+
// Include this normalizer in multiple serializers
1654+
->tag('serializer.normalizer', ['serializer' => ['api_client1', 'api_client2']])
1655+
// Include this normalizer in all serializers (including the default one)
1656+
->tag('serializer.normalizer', ['serializer' => '*'])
1657+
;
1658+
};
1659+
1660+
When the ``serializer`` attribute is not set, the service is registered with
1661+
the default serializer.
1662+
1663+
Each normalizer and encoder used in a named serializer is tagged with
1664+
a ``serializer.normalizer.<name>`` or ``serializer.encoder.<name>`` tag,
1665+
which can be used to list their priorities using the following command:
1666+
1667+
.. code-block:: terminal
1668+
1669+
$ php bin/console debug:container --tag serializer.<normalizer|encoder>.<name>
1670+
1671+
Additionally, you can exclude the default set of normalizers and encoders by
1672+
setting the ``include_built_in_normalizers`` and ``include_built_in_encoders``
1673+
options to ``false``:
1674+
1675+
.. configuration-block::
1676+
1677+
.. code-block:: yaml
1678+
1679+
# config/packages/serializer.yaml
1680+
framework:
1681+
serializer:
1682+
named_serializers:
1683+
api_client1:
1684+
include_built_in_normalizers: false
1685+
include_built_in_encoders: true
1686+
1687+
.. code-block:: xml
1688+
1689+
<!-- config/packages/serializer.xml -->
1690+
<?xml version="1.0" encoding="UTF-8" ?>
1691+
<container xmlns="http://symfony.com/schema/dic/services"
1692+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1693+
xmlns:framework="http://symfony.com/schema/dic/symfony"
1694+
xsi:schemaLocation="http://symfony.com/schema/dic/services
1695+
https://symfony.com/schema/dic/services/services-1.0.xsd
1696+
http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
1697+
1698+
<framework:config>
1699+
<framework:serializer>
1700+
1701+
<framework:named-serializer
1702+
name="api_client1"
1703+
include-built-in-normalizers="false"
1704+
include-built-in-encoders="true"
1705+
/>
1706+
1707+
</framework:serializer>
1708+
</framework:config>
1709+
</container>
1710+
1711+
.. code-block:: php
1712+
1713+
// config/packages/serializer.php
1714+
use Symfony\Config\FrameworkConfig;
1715+
1716+
return static function (FrameworkConfig $framework): void {
1717+
$framework->serializer()
1718+
->namedSerializer('api_client1')
1719+
->includeBuiltInNormalizers(false)
1720+
->includeBuiltInEncoders(true)
1721+
;
1722+
};
1723+
14751724
Debugging the Serializer
14761725
------------------------
14771726

0 commit comments

Comments
 (0)