@@ -162,6 +162,8 @@ level ignored.
162
162
163
163
In the following example we use different serialization groups for the `GET` and `PUT` operations :
164
164
165
+ [codeSelector]
166
+
165
167
` ` ` php
166
168
<?php
167
169
// api/src/Entity/Book.php
@@ -196,6 +198,29 @@ class Book
196
198
}
197
199
` ` `
198
200
201
+ ` ` ` yaml
202
+ # config/api/resources/Book.yaml
203
+ App\E ntity\B ook:
204
+ attributes:
205
+ normalization_context:
206
+ groups: ['get']
207
+ itemOperations:
208
+ get: ~
209
+ put:
210
+ normalization_context:
211
+ groups: ['put']
212
+
213
+ # config/serializer/Book.yaml
214
+ App\E ntity\B ook:
215
+ attributes:
216
+ name:
217
+ groups: ['get', 'put']
218
+ author:
219
+ groups: ['get']
220
+ ` ` `
221
+
222
+ [/codeSelector]
223
+
199
224
The `name` and `author` properties will be included in the document generated during a `GET` operation because the configuration
200
225
defined at the resource level is inherited. However the document generated when a `PUT` request will be received will only
201
226
include the `name` property because of the specific configuration for this operation.
@@ -229,6 +254,8 @@ It is possible to embed related objects (in their entirety, or only some of thei
229
254
response through the use of serialization groups. By using the following serialization groups annotations (`@Groups`),
230
255
a JSON representation of the author is embedded in the book response :
231
256
257
+ [codeSelector]
258
+
232
259
` ` ` php
233
260
<?php
234
261
// api/src/Entity/Book.php
@@ -277,6 +304,30 @@ class Person
277
304
}
278
305
` ` `
279
306
307
+ ` ` ` yaml
308
+ # config/api/resources/Book.yaml
309
+ App\E ntity\B ook:
310
+ attributes:
311
+ normalization_context:
312
+ groups: ['book']
313
+
314
+ # config/serializer/Book.yaml
315
+ App\E ntity\B ook:
316
+ attributes:
317
+ name:
318
+ groups: ['book']
319
+ author:
320
+ groups: ['book']
321
+
322
+ # config/serializer/Person.yaml
323
+ App\E ntity\P erson:
324
+ attributes:
325
+ name:
326
+ groups: ['book']
327
+ ` ` `
328
+
329
+ [/codeSelector]
330
+
280
331
The generated JSON using previous settings is below :
281
332
282
333
` ` ` json
@@ -304,6 +355,8 @@ Instead of embedding relations in the main HTTP response, you may want [to "push
304
355
It is also possible to embed a relation in `PUT` and `POST` requests. To enable that feature, set the serialization groups
305
356
the same way as normalization. For example :
306
357
358
+ [codeSelector]
359
+
307
360
` ` ` php
308
361
<?php
309
362
// api/src/Entity/Book.php
@@ -319,6 +372,16 @@ class Book
319
372
}
320
373
` ` `
321
374
375
+ ` ` ` yaml
376
+ # config/api/resources/Book.yaml
377
+ App\E ntity\B ook:
378
+ attributes:
379
+ denormalization_context:
380
+ groups: ['book']
381
+ ` ` `
382
+
383
+ [/codeSelector]
384
+
322
385
The following rules apply when denormalizing embedded relations :
323
386
324
387
* If an `@id` key is present in the embedded resource, then the object corresponding to the given URI will be retrieved through
@@ -331,6 +394,8 @@ You can specify as many embedded relation levels as you want.
331
394
332
395
It is a common problem to have entities that reference other entities of the same type :
333
396
397
+ [codeSelector]
398
+
334
399
` ` ` php
335
400
<?php
336
401
// api/src/Entity/Person.php
@@ -364,13 +429,34 @@ class Person
364
429
365
430
// ...
366
431
}
432
+ ` ` `
433
+
434
+ ` ` ` yaml
435
+ # config/api/resources/Person.yaml
436
+ App\E ntity\P erson:
437
+ attributes:
438
+ normalization_context:
439
+ groups: ['person']
440
+ denormalization_context:
441
+ groups: ['person']
367
442
443
+ # config/serializer/Person.yaml
444
+ App\E ntity\P erson:
445
+ attributes:
446
+ name:
447
+ groups: ['person']
448
+ parent:
449
+ groups: ['person']
368
450
` ` `
369
451
452
+ [/codeSelector]
453
+
370
454
The problem here is that the **$parent** property become automatically an embedded object. Besides, the property won't be shown on the OpenAPI view.
371
455
372
456
To force the **$parent** property to be used as an IRI, add an **#[ApiProperty(readableLink: false, writableLink: false)]** annotation:
373
457
458
+ [codeSelector]
459
+
374
460
` ` ` php
375
461
<?php
376
462
// api/src/Entity/Person.php
@@ -408,6 +494,30 @@ class Person
408
494
409
495
` ` `
410
496
497
+ ` ` ` yaml
498
+ # config/api/resources/Person.yaml
499
+ App\E ntity\P erson:
500
+ attributes:
501
+ normalization_context:
502
+ groups: ['person']
503
+ denormalization_context:
504
+ groups: ['person']
505
+ properties:
506
+ parent:
507
+ readableLink: false
508
+ writableLink: false
509
+
510
+ # config/serializer/Person.yaml
511
+ App\E ntity\P erson:
512
+ attributes:
513
+ name:
514
+ groups: ['person']
515
+ parent:
516
+ groups: ['person']
517
+ ` ` `
518
+
519
+ [/codeSelector]
520
+
411
521
# # Property Normalization Context
412
522
413
523
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,
@@ -521,6 +631,8 @@ class Book
521
631
522
632
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.
523
633
634
+ [codeSelector]
635
+
524
636
` ` ` php
525
637
<?php
526
638
@@ -579,12 +691,35 @@ class Greeting
579
691
}
580
692
` ` `
581
693
694
+ ` ` ` yaml
695
+ # config/api/resources/Greeting.yaml
696
+ App\E ntity\G reeting:
697
+ collectionOperations:
698
+ get:
699
+ normalization_context:
700
+ groups: 'greeting:collection:get'
701
+
702
+ # config/serializer/Greeting.yaml
703
+ App\E ntity\G reeting:
704
+ attributes:
705
+ id:
706
+ groups: 'greeting:collection:get'
707
+ name:
708
+ groups: 'greeting:collection:get'
709
+ getSum:
710
+ groups: 'greeting:collection:get'
711
+ ` ` `
712
+
713
+ [/codeSelector]
714
+
582
715
# # Changing the Serialization Context Dynamically
583
716
584
717
<p align="center" class="symfonycasts"><a href="https://symfonycasts.com/screencast/api-platform-security/service-decoration?cid=apip"><img src="../distribution/images/symfonycasts-player.png" alt="Context Builder & Service Decoration screencast"><br>Watch the Context Builder & Service Decoration screencast</a></p>
585
718
586
719
Let's imagine a resource where most fields can be managed by any user, but some can be managed only by admin users :
587
720
721
+ [codeSelector]
722
+
588
723
` ` ` php
589
724
<?php
590
725
// api/src/Entity/Book.php
@@ -624,6 +759,26 @@ class Book
624
759
}
625
760
` ` `
626
761
762
+ ` ` ` yaml
763
+ # config/api/resources/Book.yaml
764
+ App\E ntity\B ook:
765
+ attributes:
766
+ normalization_context:
767
+ groups: ['book:output']
768
+ denormalization_context:
769
+ groups: ['book:input']
770
+
771
+ # config/serializer/Book.yaml
772
+ App\E ntity\B ook:
773
+ attributes:
774
+ active:
775
+ groups: ['book:output', 'admin:input']
776
+ name:
777
+ groups: ['book:output', 'book:input']
778
+ ` ` `
779
+
780
+ [/codeSelector]
781
+
627
782
All entry points are the same for all users, so we should find a way to detect if the authenticated user is an admin, and if so
628
783
dynamically add the `admin:input` value to deserialization groups in the `$context` array.
629
784
@@ -939,6 +1094,8 @@ an IRI. A client that uses JSON-LD must send a second HTTP request to retrieve i
939
1094
You can configure API Platform to embed the JSON-LD context in the root document by adding the `jsonld_embed_context`
940
1095
attribute to the `#[ApiResource]` annotation:
941
1096
1097
+ [codeSelector]
1098
+
942
1099
` ` ` php
943
1100
<?php
944
1101
// api/src/Entity/Book.php
@@ -954,6 +1111,16 @@ class Book
954
1111
}
955
1112
` ` `
956
1113
1114
+ ` ` ` yaml
1115
+ # config/api/resources/Book.yaml
1116
+ App\E ntity\B ook:
1117
+ attributes:
1118
+ normalization_context:
1119
+ jsonld_embed_context: true
1120
+ ` ` `
1121
+
1122
+ [/codeSelector]
1123
+
957
1124
The JSON output will now include the embedded context :
958
1125
959
1126
` ` ` json
0 commit comments