You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
> As you can see in the picture above, an array is used as a man-in-the-middle. This way, Encoders will only deal with turning specific formats into arrays and vice versa. The same way, Normalizers will deal with turning specific objects into arrays and vice versa.
Unlike Symfony itself, API Platform leverages custom normalizers, its router and the [state provider](state-providers.md) system to perform an advanced transformation. Metadata are added to the generated document including links, type information, pagination data or available filters.
16
+
Unlike Symfony or Laravel themselves, API Platform leverages custom normalizers, its router and the [state provider](state-providers.md)
17
+
system to perform an advanced transformation. Metadata are added to the generated document including links, type
18
+
information, pagination data or available filters.
17
19
18
-
The API Platform Serializer is extendable. You can register custom normalizers and encoders in order to support other formats. You can also decorate existing normalizers to customize their behaviors.
20
+
The API Platform Serializer is extendable. You can register custom normalizers and encoders in order to support other formats.
21
+
You can also decorate existing normalizers to customize their behaviors.
19
22
20
23
## Available Serializers
21
24
@@ -41,7 +44,7 @@ feature of the Symfony Serializer component.
41
44
In addition to groups, you can use any option supported by the Symfony Serializer. For example, you can use [`enable_max_depth`](https://symfony.com/doc/current/components/serializer.html#handling-serialization-depth)
42
45
to limit the serialization depth.
43
46
44
-
### Configuration
47
+
### Configuration for Symfony
45
48
46
49
Just like other Symfony and API Platform components, the Serializer component can be configured using attributes, XML
47
50
or YAML. Since attributes are easy to understand, we will use them in the following examples.
@@ -69,6 +72,9 @@ framework:
69
72
70
73
## Using Serialization Groups
71
74
75
+
> [!NOTE]
76
+
> In Symfony, we use the term “Entity”, which is equivalent to Laravel “Models”.
77
+
72
78
It is simple to specify what groups to use in the API system:
73
79
74
80
1. Add the normalization context and denormalization context attributes to the resource, and specify which groups to use. Here you see that we add `read` and `write`, respectively. You can use any group names you wish.
@@ -101,6 +107,7 @@ class Book
101
107
```
102
108
103
109
```yaml
110
+
# The YAML syntax is only supported for Symfony
104
111
# api/config/api_platform/resources.yaml
105
112
resources:
106
113
App\Entity\Book:
@@ -109,6 +116,7 @@ resources:
109
116
denormalizationContext:
110
117
groups: ['write']
111
118
119
+
# The YAML syntax is only supported for Symfony
112
120
# api/config/serialization/Book.yaml
113
121
App\Entity\Book:
114
122
attributes:
@@ -119,6 +127,7 @@ App\Entity\Book:
119
127
```
120
128
121
129
```xml
130
+
<!--The XML syntax is only supported for Symfony -->
> In Symfony, we use the term “Entity”, which is equivalent to Laravel “Models”.
199
+
200
+
<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>
201
+
202
+
By default, the serializer provided with API Platform represents relations between objects using [dereferenceable IRIs](https://en.wikipedia.org/wiki/Internationalized_Resource_Identifier).
203
+
They allow you to retrieve details for related objects by issuing extra HTTP requests. However, for performance reasons, it is sometimes preferable to avoid forcing the client to issue extra HTTP requests.
204
+
205
+
187
206
It is possible to specify normalization and denormalization contexts (as well as any other attribute) on a per-operation
188
207
basis. API Platform will always use the most specific definition. For instance, if normalization groups are set both
189
208
at the resource level and at the operation level, the configuration set at the operation level will be used and the resource
@@ -219,6 +238,7 @@ class Book
219
238
```
220
239
221
240
```yaml
241
+
# The YAML syntax is only supported for Symfony
222
242
# api/config/api_platform/resources/Book.yaml
223
243
App\Entity\Book:
224
244
normalizationContext:
@@ -229,6 +249,7 @@ App\Entity\Book:
229
249
normalizationContext:
230
250
groups: ['patch']
231
251
252
+
# The YAML syntax is only supported for Symfony
232
253
# api/config/serializer/Book.yaml
233
254
App\Entity\Book:
234
255
attributes:
@@ -239,6 +260,7 @@ App\Entity\Book:
239
260
```
240
261
241
262
```xml
263
+
<!-- The XML syntax is only supported for Symfony -->
@@ -309,6 +332,9 @@ They allow you to retrieve details for related objects by issuing extra HTTP req
309
332
310
333
### Normalization
311
334
335
+
> [!NOTE]
336
+
> In Symfony, we use the term “Entity”, which is equivalent to Laravel “Models”.
337
+
312
338
In the following JSON document, the relation from a book to an author is by default represented by an URI:
313
339
314
340
```json
@@ -350,11 +376,13 @@ class Book
350
376
```
351
377
352
378
```yaml
379
+
# The YAML syntax is only supported for Symfony
353
380
# api/config/api_platform/resources/Book.yaml
354
381
App\Entity\Book:
355
382
normalizationContext:
356
383
groups: ['book']
357
384
385
+
# The YAML syntax is only supported for Symfony
358
386
# api/config/serializer/Book.yaml
359
387
App\Entity\Book:
360
388
attributes:
@@ -387,6 +415,7 @@ class Person
387
415
```
388
416
389
417
```yaml
418
+
# The YAML syntax is only supported for Symfony
390
419
# api/config/serializer/Person.yaml
391
420
App\Entity\Person:
392
421
attributes:
@@ -420,6 +449,9 @@ Instead of embedding relations in the main HTTP response, you may want [to "push
420
449
421
450
### Denormalization
422
451
452
+
> [!NOTE]
453
+
> In Symfony, we use the term “Entity”, which is equivalent to Laravel “Models”.
454
+
423
455
It is also possible to embed a relation in `PUT`, `PATCH` and `POST` requests. To enable that feature, set the serialization groups
424
456
the same way as normalization. For example:
425
457
@@ -440,6 +472,7 @@ class Book
440
472
```
441
473
442
474
```yaml
475
+
# The YAML syntax is only supported for Symfony
443
476
# api/config/api_platform/resources/Book.yaml
444
477
App\Entity\Book:
445
478
denormalizationContext:
@@ -458,6 +491,9 @@ You can specify as many embedded relation levels as you want.
458
491
459
492
### Force IRI with relations of the same type (parent/childs relations)
460
493
494
+
> [!NOTE]
495
+
> In Symfony, we use the term “Entity”, which is equivalent to Laravel “Models”.
496
+
461
497
It is a common problem to have entities that reference other entities of the same type:
462
498
463
499
<code-selector>
@@ -490,13 +526,15 @@ class Person
490
526
```
491
527
492
528
```yaml
529
+
# The YAML syntax is only supported for Symfony
493
530
# api/config/api_platform/resources/Person.yaml
494
531
App\Entity\Person:
495
532
normalizationContext:
496
533
groups: ['person']
497
534
denormalizationContext:
498
535
groups: ['person']
499
536
537
+
# The YAML syntax is only supported for Symfony
500
538
# api/config/serializer/Person.yaml
501
539
App\Entity\Person:
502
540
attributes:
@@ -542,6 +580,7 @@ class Person
542
580
```
543
581
544
582
```yaml
583
+
# The YAML syntax is only supported for Symfony
545
584
# api/config/api_platform/resources/Person.yaml
546
585
resources:
547
586
App\Entity\Person:
@@ -555,6 +594,7 @@ properties:
555
594
readableLink: false
556
595
writableLink: false
557
596
597
+
# The YAML syntax is only supported for Symfony
558
598
# api/config/serializer/Person.yaml
559
599
App\Entity\Person:
560
600
attributes:
@@ -566,7 +606,7 @@ App\Entity\Person:
566
606
567
607
</code-selector>
568
608
569
-
### Plain Identifiers
609
+
### Plain Identifiers for Symfony
570
610
571
611
Instead of sending an IRI to set a relation, you may want to send a plain identifier. To do so, you must create your own denormalizer:
572
612
@@ -617,7 +657,7 @@ class PlainIdentifierDenormalizer implements DenormalizerInterface, Denormalizer
617
657
}
618
658
```
619
659
620
-
## Property Normalization Context
660
+
## Property Normalization Context for Symfony
621
661
622
662
If you want to change the (de)normalization context of a property, for instance if you want to change the format of the date time,
623
663
you can do so by using the `#[Context]` attribute from the Symfony Serializer component.
@@ -710,6 +750,9 @@ class Book
710
750
711
751
## Calculated Field
712
752
753
+
> [!NOTE]
754
+
> In Symfony, we use the term “Entity”, which is equivalent to Laravel “Models”.
755
+
713
756
Sometimes you need to expose calculated fields. This can be done by leveraging the groups. This time not on a property, but on a method.
714
757
715
758
<code-selector>
@@ -755,13 +798,15 @@ class Greeting
755
798
```
756
799
757
800
```yaml
801
+
# The YAML syntax is only supported for Symfony
758
802
# api/config/api_platform/resources/Greeting.yaml
759
803
App\Entity\Greeting:
760
804
operations:
761
805
ApiPlatform\Metadata\GetCollection:
762
806
normalizationContext:
763
807
groups: 'greeting:collection:get'
764
808
809
+
# The YAML syntax is only supported for Symfony
765
810
# api/config/serializer/Greeting.yaml
766
811
App\Entity\Greeting:
767
812
attributes:
@@ -777,6 +822,9 @@ App\Entity\Greeting:
777
822
778
823
## Changing the Serialization Context Dynamically
779
824
825
+
> [!NOTE]
826
+
> In Symfony, we use the term “Entity”, which is equivalent to Laravel “Models”.
827
+
780
828
<p align="center" class="symfonycasts"><a href="https://symfonycasts.com/screencast/api-platform-security/service-decoration?cid=apip"><img src="../symfony/images/symfonycasts-player.png" alt="Context Builder & Service Decoration screencast"><br>Watch the Context Builder & Service Decoration screencast</a></p>
781
829
782
830
Let's imagine a resource where most fields can be managed by any user, but some can be managed only by admin users:
@@ -816,13 +864,15 @@ class Book
816
864
```
817
865
818
866
```yaml
867
+
# The YAML syntax is only supported for Symfony
819
868
# api/config/api_platform/resources/Book.yaml
820
869
App\Entity\Book:
821
870
normalizationContext:
822
871
groups: ['book:output']
823
872
denormalizationContext:
824
873
groups: ['book:input']
825
874
875
+
# The YAML syntax is only supported for Symfony
826
876
# api/config/serializer/Book.yaml
827
877
App\Entity\Book:
828
878
attributes:
@@ -842,6 +892,7 @@ API Platform implements a `ContextBuilder`, which prepares the context for seria
842
892
`createFromRequest` method:
843
893
844
894
```yaml
895
+
# The YAML syntax is only supported for Symfony
845
896
# api/config/services.yaml
846
897
services:
847
898
# ...
@@ -890,7 +941,7 @@ If the user has the `ROLE_ADMIN` permission and the subject is an instance of Bo
890
941
denormalization context. The `$normalization` variable lets you check whether the context is for normalization (if `TRUE`) or denormalization
891
942
(`FALSE`).
892
943
893
-
## Changing the Serialization Context on a Per-item Basis
944
+
## Changing the Serialization Context on a Per-item Basis for Symfony
894
945
895
946
The example above demonstrates how you can modify the normalization/denormalization context based on the current user
896
947
permissions for all books. Sometimes, however, the permissions vary depending on what book is being processed.
@@ -973,7 +1024,7 @@ instance.
973
1024
Note: In this example, we use the `TokenStorageInterface` to verify access to the book instance. However, Symfony
974
1025
provides many useful other services that might be better suited to your use case. For example, the [`AuthorizationChecker`](https://symfony.com/doc/current/components/security/authorization.html#authorization-checker).
975
1026
976
-
## Name Conversion
1027
+
## Name Conversion for Symfony
977
1028
978
1029
The Serializer Component provides a handy way to map PHP field names to serialized names. See the related [Symfony documentation](https://symfony.com/doc/current/components/serializer.html#converting-property-names-when-serializing-and-deserializing).
979
1030
@@ -994,7 +1045,7 @@ api_platform:
994
1045
995
1046
If symfony's `MetadataAwareNameConverter` is available it'll be used by default. If you specify one in ApiPlatform configuration, it'll be used. Note that you can use decoration to benefit from this name converter in your own implementation.
996
1047
997
-
## Decorating a Serializer and Adding Extra Data
1048
+
## Decorating a Serializer and Adding Extra Data for Symfony
998
1049
999
1050
In the following example, we will see how we add extra information to the serialized output. Here is how we add the
1000
1051
date on each request in `GET`:
@@ -1076,8 +1127,15 @@ final class ApiNormalizer implements NormalizerInterface, DenormalizerInterface,
1076
1127
1077
1128
## Entity Identifier Case
1078
1129
1079
-
API Platform is able to guess the entity identifier using Doctrine metadata ([ORM](https://www.doctrine-project.org/projects/doctrine-orm/en/current/reference/basic-mapping.html#identifiers-primary-keys), [MongoDB ODM](https://www.doctrine-project.org/projects/doctrine-mongodb-odm/en/current/reference/basic-mapping.html#identifiers)).
1080
-
For ORM, it also supports [composite identifiers](https://www.doctrine-project.org/projects/doctrine-orm/en/current/tutorials/composite-primary-keys.html).
1130
+
> [!NOTE]
1131
+
> In Symfony, we use the term “Entity”, which is equivalent to Laravel “Models”.
1132
+
1133
+
API Platform is able to guess the entity identifier using Doctrine metadata ([ORM](https://www.doctrine-project.org/projects/doctrine-orm/en/current/reference/basic-mapping.html#identifiers-primary-keys),
or Laravel Eloquent metadata ([ORM](https://laravel.com/docs/eloquent#primary-keys)).
1136
+
1137
+
For ORM, it also supports [Doctrine composite identifiers](https://www.doctrine-project.org/projects/doctrine-orm/en/current/tutorials/composite-primary-keys.html)
1138
+
and [Eloquent composite identifiers](https://laravel.com/docs/eloquent#composite-primary-keys).
1081
1139
1082
1140
If you are not using the Doctrine ORM or MongoDB ODM Provider, you must explicitly mark the identifier using the `identifier` attribute of
1083
1141
the `ApiPlatform\Metadata\ApiProperty` annotation. For example:
@@ -1115,6 +1173,7 @@ class Book
1115
1173
```
1116
1174
1117
1175
```yaml
1176
+
# The YAML syntax is only supported for Symfony
1118
1177
# api/config/api_platform/properties.yaml
1119
1178
properties:
1120
1179
App\Entity\Book:
@@ -1124,6 +1183,7 @@ properties:
1124
1183
1125
1184
```xml
1126
1185
<?xml version="1.0" encoding="UTF-8" ?>
1186
+
<!-- The XML syntax is only supported for Symfony -->
> In Symfony, we use the term “Entity”, which is equivalent to Laravel “Models”.
1212
+
1150
1213
By default, the generated [JSON-LD context](https://www.w3.org/TR/json-ld/#the-context) (`@context`) is only referenced by
1151
1214
an IRI. A client that uses JSON-LD must send a second HTTP request to retrieve it:
1152
1215
@@ -1180,6 +1243,7 @@ class Book
1180
1243
```
1181
1244
1182
1245
```yaml
1246
+
# The YAML syntax is only supported for Symfony
1183
1247
# api/config/api_platform/resources/Book.yaml
1184
1248
App\Entity\Book:
1185
1249
normalizationContext:
@@ -1207,6 +1271,9 @@ The JSON output will now include the embedded context:
1207
1271
1208
1272
## Collection Relation
1209
1273
1274
+
> [!NOTE]
1275
+
> In Symfony, we use the term “Entity”, which is equivalent to Laravel “Models”.
1276
+
1210
1277
This is a special case where, in an entity, you have a `toMany` relation. By default, Doctrine will use an `ArrayCollection` to store your values. This is fine when you have a _read_ operation, but when you try to _write_ you can observe an issue where the response is not reflecting the changes correctly. It can lead to client errors even though the update was correct.
1211
1278
Indeed, after an update on this relation, the collection looks wrong because `ArrayCollection`'s indices are not sequential. To change this, we recommend to use a getter that returns `$collectionRelation->getValues()`. Thanks to this, the relation is now a real array which is sequentially indexed.
0 commit comments