Skip to content

Commit 16d7666

Browse files
committed
Merge branch '7.2' into 7.3
* 7.2: Minor tweaks [Serializer] Document named serializers
2 parents 1d02e0c + bffad6d commit 16d7666

File tree

1 file changed

+248
-0
lines changed

1 file changed

+248
-0
lines changed

serializer.rst

Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1545,6 +1545,254 @@ like:
15451545
PropertyNormalizer::NORMALIZE_VISIBILITY => PropertyNormalizer::NORMALIZE_PUBLIC | PropertyNormalizer::NORMALIZE_PROTECTED,
15461546
]);
15471547

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+
15481796
Debugging the Serializer
15491797
------------------------
15501798

0 commit comments

Comments
 (0)