diff --git a/core/serialization.md b/core/serialization.md index 6c52918388a..2701a43f936 100644 --- a/core/serialization.md +++ b/core/serialization.md @@ -8,14 +8,17 @@ API Platform embraces and extends the Symfony Serializer Component to transform The main serialization process has two stages: -![Serializer workflow](../core/images/SerializerWorkflow.png) +![Serializer workflow](images/SerializerWorkflow.png) > 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. > -- [The Symfony documentation](https://symfony.com/doc/current/components/serializer.html) -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. +Unlike Symfony or Laravel themselves, 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. -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. +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. ## Available Serializers @@ -41,7 +44,7 @@ feature of the Symfony Serializer component. 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) to limit the serialization depth. -### Configuration +### Configuration for Symfony Just like other Symfony and API Platform components, the Serializer component can be configured using attributes, XML or YAML. Since attributes are easy to understand, we will use them in the following examples. @@ -71,15 +74,16 @@ framework: It is simple to specify what groups to use in the API system: -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. +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. 2. Apply the groups to properties in the object. ```php - + @@ -146,14 +153,15 @@ App\Entity\Book: - + + - + read write @@ -184,6 +192,12 @@ documentation generator. ## Using Serialization Groups per Operation +

Relations screencast
Watch the Relations screencast

+ +By default, the serializer provided with API Platform represents relations between objects using [dereferenceable IRIs](https://en.wikipedia.org/wiki/Internationalized_Resource_Identifier). +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. + It is possible to specify normalization and denormalization contexts (as well as any other attribute) on a per-operation basis. API Platform will always use the most specific definition. For instance, if normalization groups are set both at the resource level and at the operation level, the configuration set at the operation level will be used and the resource @@ -195,8 +209,8 @@ In the following example we use different serialization groups for the `GET` and ```php - + @@ -272,13 +289,14 @@ App\Entity\Book: + - + get patch @@ -330,8 +348,8 @@ the `book` group, the author will be embedded. ```php -### Plain Identifiers +### Plain Identifiers for Symfony 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: @@ -577,8 +603,8 @@ Instead of sending an IRI to set a relation, you may want to send a plain identi namespace App\Serializer; use ApiPlatform\Api\IriConverterInterface; -use App\Entity\Dummy; -use App\Entity\RelatedDummy; +use App\ApiResource\Dummy; +use App\ApiResource\RelatedDummy; use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; use Symfony\Component\Serializer\Normalizer\DenormalizerAwareInterface; use Symfony\Component\Serializer\Normalizer\DenormalizerAwareTrait; @@ -617,7 +643,7 @@ class PlainIdentifierDenormalizer implements DenormalizerInterface, Denormalizer } ``` -## Property Normalization Context +## Property Normalization Context for Symfony 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, you can do so by using the `#[Context]` attribute from the Symfony Serializer component. @@ -708,7 +734,7 @@ class Book } ``` -## Calculated Field +## Calculated Field using Doctrine 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. @@ -755,6 +781,7 @@ class Greeting ``` ```yaml +# The YAML syntax is only supported for Symfony # api/config/api_platform/resources/Greeting.yaml App\Entity\Greeting: operations: @@ -762,6 +789,7 @@ App\Entity\Greeting: normalizationContext: groups: 'greeting:collection:get' +# The YAML syntax is only supported for Symfony # api/config/serializer/Greeting.yaml App\Entity\Greeting: attributes: @@ -785,8 +813,8 @@ Let's imagine a resource where most fields can be managed by any user, but some ```php + - + ``` @@ -1140,7 +1177,7 @@ In some cases, you will want to set the identifier of a resource from the client In such cases, you must make the identifier property a writable class property. Specifically, to use client-generated IDs, you must do the following: -1. create a setter for the identifier of the entity (e.g. `public function setId(string $id)`) or make it a `public` property , +1. create a setter for the identifier of the entity/model (e.g. `public function setId(string $id)`) or make it a `public` property , 2. add the denormalization group to the property (only if you use a specific denormalization group), and, 3. if you use Doctrine ORM, be sure to **not** mark this property with [the `@GeneratedValue` annotation](http://docs.doctrine-project.org/projects/doctrine-orm/en/current/reference/basic-mapping.html#identifier-generation-strategies) or use the `NONE` value @@ -1167,8 +1204,8 @@ attribute to the `#[ApiResource]` annotation: ```php getValues()`. Thanks to this, the relation is now a real array which is sequentially indexed.