Skip to content

Commit 7c1d753

Browse files
authored
docs: add missing serialization yaml documentation (#1370)
1 parent af4da3a commit 7c1d753

File tree

1 file changed

+167
-0
lines changed

1 file changed

+167
-0
lines changed

core/serialization.md

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,8 @@ level ignored.
162162

163163
In the following example we use different serialization groups for the `GET` and `PUT` operations:
164164

165+
[codeSelector]
166+
165167
```php
166168
<?php
167169
// api/src/Entity/Book.php
@@ -196,6 +198,29 @@ class Book
196198
}
197199
```
198200

201+
```yaml
202+
# config/api/resources/Book.yaml
203+
App\Entity\Book:
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\Entity\Book:
215+
attributes:
216+
name:
217+
groups: ['get', 'put']
218+
author:
219+
groups: ['get']
220+
```
221+
222+
[/codeSelector]
223+
199224
The `name` and `author` properties will be included in the document generated during a `GET` operation because the configuration
200225
defined at the resource level is inherited. However the document generated when a `PUT` request will be received will only
201226
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
229254
response through the use of serialization groups. By using the following serialization groups annotations (`@Groups`),
230255
a JSON representation of the author is embedded in the book response:
231256

257+
[codeSelector]
258+
232259
```php
233260
<?php
234261
// api/src/Entity/Book.php
@@ -277,6 +304,30 @@ class Person
277304
}
278305
```
279306

307+
```yaml
308+
# config/api/resources/Book.yaml
309+
App\Entity\Book:
310+
attributes:
311+
normalization_context:
312+
groups: ['book']
313+
314+
# config/serializer/Book.yaml
315+
App\Entity\Book:
316+
attributes:
317+
name:
318+
groups: ['book']
319+
author:
320+
groups: ['book']
321+
322+
# config/serializer/Person.yaml
323+
App\Entity\Person:
324+
attributes:
325+
name:
326+
groups: ['book']
327+
```
328+
329+
[/codeSelector]
330+
280331
The generated JSON using previous settings is below:
281332

282333
```json
@@ -304,6 +355,8 @@ Instead of embedding relations in the main HTTP response, you may want [to "push
304355
It is also possible to embed a relation in `PUT` and `POST` requests. To enable that feature, set the serialization groups
305356
the same way as normalization. For example:
306357

358+
[codeSelector]
359+
307360
```php
308361
<?php
309362
// api/src/Entity/Book.php
@@ -319,6 +372,16 @@ class Book
319372
}
320373
```
321374

375+
```yaml
376+
# config/api/resources/Book.yaml
377+
App\Entity\Book:
378+
attributes:
379+
denormalization_context:
380+
groups: ['book']
381+
```
382+
383+
[/codeSelector]
384+
322385
The following rules apply when denormalizing embedded relations:
323386

324387
* 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.
331394

332395
It is a common problem to have entities that reference other entities of the same type:
333396

397+
[codeSelector]
398+
334399
```php
335400
<?php
336401
// api/src/Entity/Person.php
@@ -364,13 +429,34 @@ class Person
364429
365430
// ...
366431
}
432+
```
433+
434+
```yaml
435+
# config/api/resources/Person.yaml
436+
App\Entity\Person:
437+
attributes:
438+
normalization_context:
439+
groups: ['person']
440+
denormalization_context:
441+
groups: ['person']
367442
443+
# config/serializer/Person.yaml
444+
App\Entity\Person:
445+
attributes:
446+
name:
447+
groups: ['person']
448+
parent:
449+
groups: ['person']
368450
```
369451

452+
[/codeSelector]
453+
370454
The problem here is that the **$parent** property become automatically an embedded object. Besides, the property won't be shown on the OpenAPI view.
371455

372456
To force the **$parent** property to be used as an IRI, add an **#[ApiProperty(readableLink: false, writableLink: false)]** annotation:
373457

458+
[codeSelector]
459+
374460
```php
375461
<?php
376462
// api/src/Entity/Person.php
@@ -408,6 +494,30 @@ class Person
408494
409495
```
410496

497+
```yaml
498+
# config/api/resources/Person.yaml
499+
App\Entity\Person:
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\Entity\Person:
512+
attributes:
513+
name:
514+
groups: ['person']
515+
parent:
516+
groups: ['person']
517+
```
518+
519+
[/codeSelector]
520+
411521
## Property Normalization Context
412522

413523
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
521631

522632
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.
523633

634+
[codeSelector]
635+
524636
```php
525637
<?php
526638
@@ -579,12 +691,35 @@ class Greeting
579691
}
580692
```
581693

694+
```yaml
695+
# config/api/resources/Greeting.yaml
696+
App\Entity\Greeting:
697+
collectionOperations:
698+
get:
699+
normalization_context:
700+
groups: 'greeting:collection:get'
701+
702+
# config/serializer/Greeting.yaml
703+
App\Entity\Greeting:
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+
582715
## Changing the Serialization Context Dynamically
583716

584717
<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>
585718

586719
Let's imagine a resource where most fields can be managed by any user, but some can be managed only by admin users:
587720

721+
[codeSelector]
722+
588723
```php
589724
<?php
590725
// api/src/Entity/Book.php
@@ -624,6 +759,26 @@ class Book
624759
}
625760
```
626761

762+
```yaml
763+
# config/api/resources/Book.yaml
764+
App\Entity\Book:
765+
attributes:
766+
normalization_context:
767+
groups: ['book:output']
768+
denormalization_context:
769+
groups: ['book:input']
770+
771+
# config/serializer/Book.yaml
772+
App\Entity\Book:
773+
attributes:
774+
active:
775+
groups: ['book:output', 'admin:input']
776+
name:
777+
groups: ['book:output', 'book:input']
778+
```
779+
780+
[/codeSelector]
781+
627782
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
628783
dynamically add the `admin:input` value to deserialization groups in the `$context` array.
629784

@@ -939,6 +1094,8 @@ an IRI. A client that uses JSON-LD must send a second HTTP request to retrieve i
9391094
You can configure API Platform to embed the JSON-LD context in the root document by adding the `jsonld_embed_context`
9401095
attribute to the `#[ApiResource]` annotation:
9411096

1097+
[codeSelector]
1098+
9421099
```php
9431100
<?php
9441101
// api/src/Entity/Book.php
@@ -954,6 +1111,16 @@ class Book
9541111
}
9551112
```
9561113

1114+
```yaml
1115+
# config/api/resources/Book.yaml
1116+
App\Entity\Book:
1117+
attributes:
1118+
normalization_context:
1119+
jsonld_embed_context: true
1120+
```
1121+
1122+
[/codeSelector]
1123+
9571124
The JSON output will now include the embedded context:
9581125

9591126
```json

0 commit comments

Comments
 (0)