Skip to content

Commit 20fef44

Browse files
committed
docs(serialization): support for laravel and fix image
1 parent de4ec84 commit 20fef44

File tree

1 file changed

+79
-12
lines changed

1 file changed

+79
-12
lines changed

core/serialization.md

Lines changed: 79 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,17 @@ API Platform embraces and extends the Symfony Serializer Component to transform
88

99
The main serialization process has two stages:
1010

11-
![Serializer workflow](../core/images/SerializerWorkflow.png)
11+
![Serializer workflow](images/SerializerWorkflow.png)
1212

1313
> 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.
1414
> -- [The Symfony documentation](https://symfony.com/doc/current/components/serializer.html)
1515
16-
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.
1719

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.
1922

2023
## Available Serializers
2124

@@ -41,7 +44,7 @@ feature of the Symfony Serializer component.
4144
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)
4245
to limit the serialization depth.
4346

44-
### Configuration
47+
### Configuration for Symfony
4548

4649
Just like other Symfony and API Platform components, the Serializer component can be configured using attributes, XML
4750
or YAML. Since attributes are easy to understand, we will use them in the following examples.
@@ -69,6 +72,9 @@ framework:
6972

7073
## Using Serialization Groups
7174

75+
> [!NOTE]
76+
> In Symfony, we use the term “Entity”, which is equivalent to Laravel “Models”.
77+
7278
It is simple to specify what groups to use in the API system:
7379

7480
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
101107
```
102108

103109
```yaml
110+
# The YAML syntax is only supported for Symfony
104111
# api/config/api_platform/resources.yaml
105112
resources:
106113
App\Entity\Book:
@@ -109,6 +116,7 @@ resources:
109116
denormalizationContext:
110117
groups: ['write']
111118
119+
# The YAML syntax is only supported for Symfony
112120
# api/config/serialization/Book.yaml
113121
App\Entity\Book:
114122
attributes:
@@ -119,6 +127,7 @@ App\Entity\Book:
119127
```
120128

121129
```xml
130+
<!--The XML syntax is only supported for Symfony -->
122131
<!-- api/config/api_platform/resources.xml -->
123132
<?xml version="1.0" encoding="UTF-8" ?>
124133
<resources xmlns="https://api-platform.com/schema/metadata/resources-3.0"
@@ -146,7 +155,8 @@ App\Entity\Book:
146155
</denormalizationContext>
147156
</resource>
148157
</resources>
149-
158+
159+
<!--The XML syntax is only supported for Symfony -->
150160
<!-- api/config/serialization/Book.xml -->
151161
<?xml version="1.0" encoding="UTF-8" ?>
152162
<serializer xmlns="http://symfony.com/schema/dic/serializer-mapping"
@@ -184,6 +194,15 @@ documentation generator.
184194

185195
## Using Serialization Groups per Operation
186196

197+
> [!NOTE]
198+
> 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+
187206
It is possible to specify normalization and denormalization contexts (as well as any other attribute) on a per-operation
188207
basis. API Platform will always use the most specific definition. For instance, if normalization groups are set both
189208
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
219238
```
220239

221240
```yaml
241+
# The YAML syntax is only supported for Symfony
222242
# api/config/api_platform/resources/Book.yaml
223243
App\Entity\Book:
224244
normalizationContext:
@@ -229,6 +249,7 @@ App\Entity\Book:
229249
normalizationContext:
230250
groups: ['patch']
231251
252+
# The YAML syntax is only supported for Symfony
232253
# api/config/serializer/Book.yaml
233254
App\Entity\Book:
234255
attributes:
@@ -239,6 +260,7 @@ App\Entity\Book:
239260
```
240261

241262
```xml
263+
<!-- The XML syntax is only supported for Symfony -->
242264
<!-- api/config/api_platform/resources.xml -->
243265
<?xml version="1.0" encoding="UTF-8" ?>
244266
<resources xmlns="https://api-platform.com/schema/metadata/resources-3.0"
@@ -272,6 +294,7 @@ App\Entity\Book:
272294
</resource>
273295
</resources>
274296
297+
<!-- The XML syntax is only supported for Symfony -->
275298
<!-- api/config/serialization/Book.xml -->
276299
<?xml version="1.0" encoding="UTF-8" ?>
277300
<serializer xmlns="http://symfony.com/schema/dic/serializer-mapping"
@@ -309,6 +332,9 @@ They allow you to retrieve details for related objects by issuing extra HTTP req
309332

310333
### Normalization
311334

335+
> [!NOTE]
336+
> In Symfony, we use the term “Entity”, which is equivalent to Laravel “Models”.
337+
312338
In the following JSON document, the relation from a book to an author is by default represented by an URI:
313339

314340
```json
@@ -350,11 +376,13 @@ class Book
350376
```
351377

352378
```yaml
379+
# The YAML syntax is only supported for Symfony
353380
# api/config/api_platform/resources/Book.yaml
354381
App\Entity\Book:
355382
normalizationContext:
356383
groups: ['book']
357384
385+
# The YAML syntax is only supported for Symfony
358386
# api/config/serializer/Book.yaml
359387
App\Entity\Book:
360388
attributes:
@@ -387,6 +415,7 @@ class Person
387415
```
388416

389417
```yaml
418+
# The YAML syntax is only supported for Symfony
390419
# api/config/serializer/Person.yaml
391420
App\Entity\Person:
392421
attributes:
@@ -420,6 +449,9 @@ Instead of embedding relations in the main HTTP response, you may want [to "push
420449

421450
### Denormalization
422451

452+
> [!NOTE]
453+
> In Symfony, we use the term “Entity”, which is equivalent to Laravel “Models”.
454+
423455
It is also possible to embed a relation in `PUT`, `PATCH` and `POST` requests. To enable that feature, set the serialization groups
424456
the same way as normalization. For example:
425457

@@ -440,6 +472,7 @@ class Book
440472
```
441473

442474
```yaml
475+
# The YAML syntax is only supported for Symfony
443476
# api/config/api_platform/resources/Book.yaml
444477
App\Entity\Book:
445478
denormalizationContext:
@@ -458,6 +491,9 @@ You can specify as many embedded relation levels as you want.
458491

459492
### Force IRI with relations of the same type (parent/childs relations)
460493

494+
> [!NOTE]
495+
> In Symfony, we use the term “Entity”, which is equivalent to Laravel “Models”.
496+
461497
It is a common problem to have entities that reference other entities of the same type:
462498

463499
<code-selector>
@@ -490,13 +526,15 @@ class Person
490526
```
491527

492528
```yaml
529+
# The YAML syntax is only supported for Symfony
493530
# api/config/api_platform/resources/Person.yaml
494531
App\Entity\Person:
495532
normalizationContext:
496533
groups: ['person']
497534
denormalizationContext:
498535
groups: ['person']
499536
537+
# The YAML syntax is only supported for Symfony
500538
# api/config/serializer/Person.yaml
501539
App\Entity\Person:
502540
attributes:
@@ -542,6 +580,7 @@ class Person
542580
```
543581

544582
```yaml
583+
# The YAML syntax is only supported for Symfony
545584
# api/config/api_platform/resources/Person.yaml
546585
resources:
547586
App\Entity\Person:
@@ -555,6 +594,7 @@ properties:
555594
readableLink: false
556595
writableLink: false
557596
597+
# The YAML syntax is only supported for Symfony
558598
# api/config/serializer/Person.yaml
559599
App\Entity\Person:
560600
attributes:
@@ -566,7 +606,7 @@ App\Entity\Person:
566606

567607
</code-selector>
568608

569-
### Plain Identifiers
609+
### Plain Identifiers for Symfony
570610

571611
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:
572612

@@ -617,7 +657,7 @@ class PlainIdentifierDenormalizer implements DenormalizerInterface, Denormalizer
617657
}
618658
```
619659

620-
## Property Normalization Context
660+
## Property Normalization Context for Symfony
621661

622662
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,
623663
you can do so by using the `#[Context]` attribute from the Symfony Serializer component.
@@ -710,6 +750,9 @@ class Book
710750

711751
## Calculated Field
712752

753+
> [!NOTE]
754+
> In Symfony, we use the term “Entity”, which is equivalent to Laravel “Models”.
755+
713756
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.
714757

715758
<code-selector>
@@ -755,13 +798,15 @@ class Greeting
755798
```
756799

757800
```yaml
801+
# The YAML syntax is only supported for Symfony
758802
# api/config/api_platform/resources/Greeting.yaml
759803
App\Entity\Greeting:
760804
operations:
761805
ApiPlatform\Metadata\GetCollection:
762806
normalizationContext:
763807
groups: 'greeting:collection:get'
764808
809+
# The YAML syntax is only supported for Symfony
765810
# api/config/serializer/Greeting.yaml
766811
App\Entity\Greeting:
767812
attributes:
@@ -777,6 +822,9 @@ App\Entity\Greeting:
777822

778823
## Changing the Serialization Context Dynamically
779824

825+
> [!NOTE]
826+
> In Symfony, we use the term “Entity”, which is equivalent to Laravel “Models”.
827+
780828
<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>
781829

782830
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
816864
```
817865

818866
```yaml
867+
# The YAML syntax is only supported for Symfony
819868
# api/config/api_platform/resources/Book.yaml
820869
App\Entity\Book:
821870
normalizationContext:
822871
groups: ['book:output']
823872
denormalizationContext:
824873
groups: ['book:input']
825874
875+
# The YAML syntax is only supported for Symfony
826876
# api/config/serializer/Book.yaml
827877
App\Entity\Book:
828878
attributes:
@@ -842,6 +892,7 @@ API Platform implements a `ContextBuilder`, which prepares the context for seria
842892
`createFromRequest` method:
843893

844894
```yaml
895+
# The YAML syntax is only supported for Symfony
845896
# api/config/services.yaml
846897
services:
847898
# ...
@@ -890,7 +941,7 @@ If the user has the `ROLE_ADMIN` permission and the subject is an instance of Bo
890941
denormalization context. The `$normalization` variable lets you check whether the context is for normalization (if `TRUE`) or denormalization
891942
(`FALSE`).
892943

893-
## Changing the Serialization Context on a Per-item Basis
944+
## Changing the Serialization Context on a Per-item Basis for Symfony
894945

895946
The example above demonstrates how you can modify the normalization/denormalization context based on the current user
896947
permissions for all books. Sometimes, however, the permissions vary depending on what book is being processed.
@@ -973,7 +1024,7 @@ instance.
9731024
Note: In this example, we use the `TokenStorageInterface` to verify access to the book instance. However, Symfony
9741025
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).
9751026

976-
## Name Conversion
1027+
## Name Conversion for Symfony
9771028

9781029
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).
9791030

@@ -994,7 +1045,7 @@ api_platform:
9941045

9951046
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.
9961047

997-
## Decorating a Serializer and Adding Extra Data
1048+
## Decorating a Serializer and Adding Extra Data for Symfony
9981049

9991050
In the following example, we will see how we add extra information to the serialized output. Here is how we add the
10001051
date on each request in `GET`:
@@ -1076,8 +1127,15 @@ final class ApiNormalizer implements NormalizerInterface, DenormalizerInterface,
10761127

10771128
## Entity Identifier Case
10781129

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),
1134+
[MongoDB ODM](https://www.doctrine-project.org/projects/doctrine-mongodb-odm/en/current/reference/basic-mapping.html#identifiers))
1135+
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).
10811139

10821140
If you are not using the Doctrine ORM or MongoDB ODM Provider, you must explicitly mark the identifier using the `identifier` attribute of
10831141
the `ApiPlatform\Metadata\ApiProperty` annotation. For example:
@@ -1115,6 +1173,7 @@ class Book
11151173
```
11161174

11171175
```yaml
1176+
# The YAML syntax is only supported for Symfony
11181177
# api/config/api_platform/properties.yaml
11191178
properties:
11201179
App\Entity\Book:
@@ -1124,6 +1183,7 @@ properties:
11241183

11251184
```xml
11261185
<?xml version="1.0" encoding="UTF-8" ?>
1186+
<!-- The XML syntax is only supported for Symfony -->
11271187
<!-- api/config/api_platform/properties.xml -->
11281188
11291189
<properties xmlns="https://api-platform.com/schema/metadata/properties-3.0"
@@ -1147,6 +1207,9 @@ must do the following:
11471207

11481208
## Embedding the JSON-LD Context
11491209

1210+
> [!NOTE]
1211+
> In Symfony, we use the term “Entity”, which is equivalent to Laravel “Models”.
1212+
11501213
By default, the generated [JSON-LD context](https://www.w3.org/TR/json-ld/#the-context) (`@context`) is only referenced by
11511214
an IRI. A client that uses JSON-LD must send a second HTTP request to retrieve it:
11521215

@@ -1180,6 +1243,7 @@ class Book
11801243
```
11811244

11821245
```yaml
1246+
# The YAML syntax is only supported for Symfony
11831247
# api/config/api_platform/resources/Book.yaml
11841248
App\Entity\Book:
11851249
normalizationContext:
@@ -1207,6 +1271,9 @@ The JSON output will now include the embedded context:
12071271

12081272
## Collection Relation
12091273

1274+
> [!NOTE]
1275+
> In Symfony, we use the term “Entity”, which is equivalent to Laravel “Models”.
1276+
12101277
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.
12111278
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.
12121279

0 commit comments

Comments
 (0)