@@ -389,7 +389,7 @@ the specific configuration for this operation.
389389
390390Refer to the [operations](operations.md) documentation to learn more.
391391
392- # # Embedding Relations
392+ # # Embedding Relations With Serialization Groups
393393
394394<p align="center" class="symfonycasts"><a href="https://symfonycasts.com/screencast/api-platform/relations?cid=apip"><img src="../symfony/images/symfonycasts-player.png" alt="Relations screencast"><br>Watch the Relations screencast</a></p>
395395
@@ -727,6 +727,352 @@ class PlainIdentifierDenormalizer implements DenormalizerInterface, Denormalizer
727727}
728728` ` `
729729
730+ # # Using Serialization Attributes
731+
732+ In addition to using serialization groups, you can specify which attributes (properties) of a
733+ resource should be exposed during normalization (read) and denormalization (write) processes. This
734+ is done through the `attributes` key in the serialization context.
735+
736+ It is simple to specify which attributes to use in the API system :
737+
738+ Add the normalization context and denormalization context to the resource, and specify which
739+ attributes to expose.
740+
741+ <code-selector>
742+
743+ ` ` ` php
744+ <?php
745+ // api/src/ApiResource/Book.php with Symfony or app/ApiResource/Book.php with Laravel
746+ namespace App\A piResource;
747+
748+ use ApiPlatform\M etadata\A piResource;
749+
750+ #[ApiResource(
751+ normalizationContext: [
752+ 'attributes' => ['id', 'title'],
753+ ],
754+ denormalizationContext: [
755+ 'attributes' => ['title'],
756+ ],
757+ )]
758+ class Book
759+ {
760+ public ?int $id = null;
761+
762+ public string $title = '';
763+
764+ public string $isbn = '';
765+
766+ // ...
767+ }
768+ ` ` `
769+
770+ ` ` ` yaml
771+ # The YAML syntax is only supported for Symfony
772+ # api/config/api_platform/resources/Book.yaml
773+ App\A piResource\B ook:
774+ normalizationContext:
775+ attributes: ["id", "title"]
776+ denormalizationContext:
777+ attributes: ["title"]
778+ ` ` `
779+
780+ ` ` ` xml
781+ <!-- The XML syntax is only supported for Symfony -->
782+ <!-- api/config/api_platform/resources.xml -->
783+ <?xml version="1.0" encoding="UTF-8" ?>
784+ <resources xmlns="https://api-platform.com/schema/metadata/resources-3.0"
785+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
786+ xsi:schemaLocation="https://api-platform.com/schema/metadata/resources-3.0
787+ https://api-platform.com/schema/metadata/resources-3.0.xsd">
788+ <resource class="App\A piResource\B ook">
789+ <normalizationContext>
790+ <values>
791+ <value name="attributes">
792+ <values>
793+ <value>id</value>
794+ <value>title</value>
795+ </values>
796+ </value>
797+ </values>
798+ </normalizationContext>
799+ <denormalizationContext>
800+ <values>
801+ <value name="attributes">
802+ <values>
803+ <value>title</value>
804+ </values>
805+ </value>
806+ </values>
807+ </denormalizationContext>
808+ </resource>
809+ </resources>
810+ ` ` `
811+
812+ </code-selector>
813+
814+ In the previous example, the `id` and `title` properties will be visible when reading (`GET`) the
815+ object. When writing (`PUT` / `PATCH` / `POST`), only `title` is accepted. The `isbn` property is
816+ never exposed because it was not specified in the attributes list.
817+
818+ Internally, API Platform passes the value of the `normalizationContext` as the 3rd argument of
819+ [the `Serializer::serialize()` method](https://api.symfony.com/master/Symfony/Component/Serializer/SerializerInterface.html#method_serialize)
820+ during the normalization process. `denormalizationContext` is passed as the 4th argument of
821+ [the `Serializer::deserialize()` method](https://api.symfony.com/master/Symfony/Component/Serializer/SerializerInterface.html#method_deserialize)
822+ during denormalization (writing).
823+
824+ In addition to the `attributes` key, you can configure any Symfony Serializer option through the
825+ ` $context` parameter (e.g. the `enable_max_depth` key when using
826+ [the `@MaxDepth` annotation](https://symfony.com/doc/current/components/serializer.html#handling-serialization-depth)).
827+
828+ Any attributes configuration that you specify will also be leveraged by the built-in actions and the
829+ OpenAPI documentation generator.
830+
831+ # # Using Serialization Attributes per Operation
832+
833+ It is possible to specify normalization and denormalization contexts (as well as any other
834+ attribute) on a per-operation basis. API Platform will always use the most specific definition. For
835+ instance, if normalization attributes are set both at the resource level and at the operation level,
836+ the configuration set at the operation level will be used and the resource level ignored.
837+
838+ In the following example we use different attributes for the `GET` and `POST` operations :
839+
840+ <code-selector>
841+
842+ ` ` ` php
843+ <?php
844+ // api/src/ApiResource/Book.php with Symfony or app/ApiResource/Book.php with Laravel
845+ namespace App\A piResource;
846+
847+ use ApiPlatform\M etadata\A piResource;
848+ use ApiPlatform\M etadata\G et;
849+ use ApiPlatform\M etadata\P ost;
850+
851+ #[ApiResource]
852+ #[Get(
853+ normalizationContext: [
854+ 'attributes' => ['id', 'title'],
855+ ],
856+ )]
857+ #[Post(
858+ denormalizationContext: [
859+ 'attributes' => ['title'],
860+ ],
861+ normalizationContext: [
862+ 'attributes' => ['id', 'title'],
863+ ],
864+ )]
865+ class Book
866+ {
867+ public ?int $id = null;
868+
869+ public string $title = '';
870+
871+ public ?string $name = null;
872+
873+ public string $isbn = '';
874+
875+ // ...
876+ }
877+ ` ` `
878+
879+ ` ` ` yaml
880+ # The YAML syntax is only supported for Symfony
881+ # api/config/api_platform/resources/Book.yaml
882+ App\A piResource\B ook:
883+ operations:
884+ ApiPlatform\M etadata\G et:
885+ normalizationContext:
886+ attributes: ["id", "title"]
887+ ApiPlatform\M etadata\P ost:
888+ denormalizationContext:
889+ attributes: ["title"]
890+ normalizationContext:
891+ attributes: ["id", "title"]
892+ ` ` `
893+
894+ ` ` ` xml
895+ <!-- The XML syntax is only supported for Symfony -->
896+ <!-- api/config/api_platform/resources.xml -->
897+ <?xml version="1.0" encoding="UTF-8" ?>
898+ <resources xmlns="https://api-platform.com/schema/metadata/resources-3.0"
899+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
900+ xsi:schemaLocation="https://api-platform.com/schema/metadata/resources-3.0
901+ https://api-platform.com/schema/metadata/resources-3.0.xsd">
902+ <resource class="App\A piResource\B ook">
903+ <operations>
904+ <operation class="ApiPlatform\M etadata\G et">
905+ <normalizationContext>
906+ <values>
907+ <value name="attributes">
908+ <values>
909+ <value>id</value>
910+ <value>title</value>
911+ </values>
912+ </value>
913+ </values>
914+ </normalizationContext>
915+ </operation>
916+ <operation class="ApiPlatform\M etadata\P ost">
917+ <denormalizationContext>
918+ <values>
919+ <value name="attributes">
920+ <values>
921+ <value>title</value>
922+ </values>
923+ </value>
924+ </values>
925+ </denormalizationContext>
926+ <normalizationContext>
927+ <values>
928+ <value name="attributes">
929+ <values>
930+ <value>id</value>
931+ <value>title</value>
932+ </values>
933+ </value>
934+ </values>
935+ </normalizationContext>
936+ </operation>
937+ </operations>
938+ </resource>
939+ </resources>
940+ ` ` `
941+
942+ </code-selector>
943+
944+ The `id` and `title` attributes will be included in the document generated during both `GET` and
945+ ` POST` operations because the operation-specific configuration is used. When writing (`POST`), only
946+ ` title` is accepted in the request.
947+
948+ Refer to the [operations](operations.md) documentation to learn more.
949+
950+ # # Embedding Relations With Serialization Attributes
951+
952+ When you include related resources (like an author in a book), you can control which attributes of
953+ those related resources are exposed by using nested attribute definitions. This is useful when you
954+ want to limit the data returned for related objects without creating separate operations.
955+
956+ In the following example, we use nested attribute filtering to expose only specific fields of
957+ related resources :
958+
959+ <code-selector>
960+
961+ ` ` ` php
962+ <?php
963+ // api/src/ApiResource/Book.php with Symfony or app/ApiResource/Book.php with Laravel
964+ namespace App\A piResource;
965+
966+ use ApiPlatform\M etadata\A piResource;
967+
968+ #[ApiResource(
969+ normalizationContext: [
970+ 'attributes' => ['id', 'title', 'author' => ['id', 'name']],
971+ ],
972+ )]
973+ class Book
974+ {
975+ public ?int $id = null;
976+
977+ public string $title = '';
978+
979+ public Author $author;
980+
981+ public string $isbn = '';
982+
983+ // ...
984+ }
985+ ` ` `
986+
987+ ` ` ` yaml
988+ # The YAML syntax is only supported for Symfony
989+ # api/config/api_platform/resources/Book.yaml
990+ App\A piResource\B ook:
991+ normalizationContext:
992+ attributes:
993+ - id
994+ - title
995+ - author:
996+ - id
997+ - name
998+ ` ` `
999+
1000+ ` ` ` xml
1001+ <!-- The XML syntax is only supported for Symfony -->
1002+ <!-- api/config/api_platform/resources.xml -->
1003+ <?xml version="1.0" encoding="UTF-8" ?>
1004+ <resources xmlns="https://api-platform.com/schema/metadata/resources-3.0"
1005+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1006+ xsi:schemaLocation="https://api-platform.com/schema/metadata/resources-3.0
1007+ https://api-platform.com/schema/metadata/resources-3.0.xsd">
1008+ <resource class="App\A piResource\B ook">
1009+ <normalizationContext>
1010+ <values>
1011+ <value name="attributes">
1012+ <values>
1013+ <value>id</value>
1014+ <value>title</value>
1015+ <value key="author">
1016+ <values>
1017+ <value>id</value>
1018+ <value>name</value>
1019+ </values>
1020+ </value>
1021+ </values>
1022+ </value>
1023+ </values>
1024+ </normalizationContext>
1025+ </resource>
1026+ </resources>
1027+ ` ` `
1028+
1029+ </code-selector>
1030+
1031+ <code-selector>
1032+
1033+ ` ` ` php
1034+ <?php
1035+ // api/src/ApiResource/Author.php with Symfony or app/ApiResource/Author.php with Laravel
1036+ namespace App\A piResource;
1037+
1038+ use ApiPlatform\M etadata\A piResource;
1039+
1040+ #[ApiResource]
1041+ class Author
1042+ {
1043+ public ?int $id = null;
1044+
1045+ public string $name;
1046+
1047+ // ...
1048+ }
1049+ ` ` `
1050+
1051+ ` ` ` yaml
1052+ # The YAML syntax is only supported for Symfony
1053+ # api/config/api_platform/resources/Author.yaml
1054+ App\A piResource\A uthor: ~
1055+ ` ` `
1056+
1057+ ` ` ` xml
1058+ <!-- The XML syntax is only supported for Symfony -->
1059+ <!-- api/config/api_platform/resources.xml -->
1060+ <?xml version="1.0" encoding="UTF-8" ?>
1061+ <resources xmlns="https://api-platform.com/schema/metadata/resources-3.0"
1062+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1063+ xsi:schemaLocation="https://api-platform.com/schema/metadata/resources-3.0
1064+ https://api-platform.com/schema/metadata/resources-3.0.xsd">
1065+ <resource class="App\A piResource\A uthor" />
1066+ </resources>
1067+ ` ` `
1068+
1069+ </code-selector>
1070+
1071+ In this example, the `author` property will be included in the response with only its `id` and
1072+ ` name` attributes visible. Other attributes of the Author resource will be filtered out. The nested
1073+ attribute syntax `'author' => ['id', 'name']` instructs the serializer to only expose those
1074+ specified attributes of the related object.
1075+
7301076# # Property Normalization Context for Symfony
7311077
7321078If you want to change the (de)normalization context of a property, for instance if you want to
0 commit comments