Skip to content

Commit 9ba4b91

Browse files
committed
Add docs for data persisters
1 parent b3d9a00 commit 9ba4b91

File tree

3 files changed

+84
-14
lines changed

3 files changed

+84
-14
lines changed

core/data-persisters.md

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Data Persisters
2+
3+
To mutate the application states during `POST`, `PUT`, `PATCH` or `DELETE` [operations](operations.md), API Platform calls
4+
classes called **data persisters**. Data persisters receive an instance of the class marked as an API resource (usually using
5+
the `@ApiResource` annotation). This instance has been created using data submitted by the client during [the deserialization
6+
process](serialization.md).
7+
8+
A data persister using [Doctrine ORM](http://www.doctrine-project.org/projects/orm.html) is included with the library and
9+
is enabled by default. It is able to persist and delete objects that are also mapped as [Doctrine entities](https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/basic-mapping.html).
10+
11+
However, you may want to store data to other persistence layers (ElasticSearch or MongoDB), to separate the public model
12+
of the API and the internal model mapped with the database; or to use patterns such as [CQRS](https://martinfowler.com/bliki/CQRS.html)
13+
to use a separate model for [read operations](data-providers.md) and for updates.
14+
15+
Custom data persisters can be used to do so. A project can include as many data persisters as it needs. The first able to
16+
persist data for a given resource will be used.
17+
18+
## Creating a Custom Data Persister
19+
20+
To create a data persister, you have to implement the [`DataPersisterInterface`](https://github.com/api-platform/core/blob/master/src/DataPersister/DataPersisterInterface.php).
21+
This interface defines only 3 methods:
22+
23+
* `persist`: to create or update the given data
24+
* `delete`: to delete the given data
25+
* `support`: to tell if the given data xcan be handled by this specific data persister
26+
27+
Here is an example implementation:
28+
29+
```php
30+
namespace App\DataPersister;
31+
32+
use ApiPlatform\Core\DataPersister\DataPersisterInterface;
33+
use App\Entity\BlogPost;
34+
35+
final class BlogPostDataPersister implements DataPersisterInterface
36+
{
37+
public function supports($data): bool
38+
{
39+
return $data instanceof BlogPost;
40+
}
41+
42+
public function persist($data)
43+
{
44+
// call your persistence layer to save $data
45+
return $data;
46+
}
47+
48+
public function delete($data): void
49+
{
50+
// call your persistence layer to delete $data
51+
}
52+
}
53+
```
54+
55+
If service autowiring and autoconfiguration are enabled (it's the case by default), you are done!
56+
57+
Otherwise, if you use a custom dependency injection configuration, you need to register the corresponding service and add the
58+
`api_platform.data_persister` tag to it. As for collection data providers, the `priority` attribute can be used to order
59+
providers.
60+
61+
```yaml
62+
# api/config/services.yaml
63+
services:
64+
# ...
65+
'App\DataPersister\BlogPostDataPersister': ~
66+
# Uncomment only if autoconfiguration is disabled
67+
#tags: [ 'api_platform.data_persister' ]
68+
```

core/data-providers.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ final class BlogPostCollectionDataProvider implements CollectionDataProviderInte
5858
}
5959
```
6060

61-
Then declare a Symfony service, for example:
61+
If you use the default configuration, the corresponding service will be automatically registered thanks to the [autowiring](https://symfony.com/doc/current/service_container/autowiring.html).
62+
To declare the service explicitly, or to set a custom priority, you can use the following snippet:
6263

6364
```yaml
6465
# api/config/services.yaml

index.md

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,12 @@
8080
1. [Custom Collection Data Provider](core/data-providers.md#custom-collection-data-provider)
8181
2. [Custom Item Data Provider](core/data-providers.md#custom-item-data-provider)
8282
3. [Injecting the Serializer in an `ItemDataProvider`](core/data-providers.md#injecting-the-serializer-in-an-itemdataprovider)
83-
16. [Extensions](core/extensions.md)
83+
16. [Data Persisters](core/data-persisters.md)
84+
17. [Extensions](core/extensions.md)
8485
1. [Custom Extension](core/extensions.md#custom-extension)
8586
2. [Filter upon the current user](core/extensions.md#example)
86-
17. [Security](core/security.md)
87-
18. [Performance](core/performance.md)
87+
18. [Security](core/security.md)
88+
19. [Performance](core/performance.md)
8889
1. [Enabling the Built-in HTTP Cache Invalidation System](core/performance.md#enabling-the-builtin-http-cache-invalidation-system)
8990
2. [Enabling the Metadata Cache](core/performance.md#enabling-the-metadata-cache)
9091
3. [Using PPM (PHP-PM)](core/performance.md#using-ppm-php-pm)
@@ -96,32 +97,32 @@
9697
3. [Override at Resource and Operation Level](core/performance.md#override-at-resource-and-operation-level)
9798
4. [Disable Eager Loading](core/performance.md#disable-eager-loading)
9899
3. [Partial Pagination](core/performance.md#partial-pagination)
99-
19. [Operation Path Naming](core/operation-path-naming.md)
100+
20. [Operation Path Naming](core/operation-path-naming.md)
100101
1. [Configuration](core/operation-path-naming.md#configuration)
101102
2. [Create a Custom Operation Path Naming](core/operation-path-naming.md#create-a-custom-operation-path-resolver)
102103
1. [Defining the Operation Path Naming](core/operation-path-naming.md#defining-the-operation-path-resolver)
103104
2. [Registering the Service](core/operation-path-naming.md#registering-the-service)
104105
3. [Configure it](core/operation-path-naming.md#configure-it)
105-
20. [Accept application/x-www-form-urlencoded Form Data](core/form-data.md)
106-
21. [FOSUserBundle Integration](core/fosuser-bundle.md)
106+
21. [Accept application/x-www-form-urlencoded Form Data](core/form-data.md)
107+
22. [FOSUserBundle Integration](core/fosuser-bundle.md)
107108
1. [Installing the Bundle](core/fosuser-bundle.md#installing-the-bundle)
108109
2. [Enabling the Bridge](core/fosuser-bundle.md#enabling-the-bridge)
109110
3. [Creating a `User` Entity with Serialization Groups](core/fosuser-bundle.md#creating-a-user-entity-with-serialization-groups)
110-
22. [Adding a JWT authentication using LexikJWTAuthenticationBundle](core/jwt.md)
111+
23. [Adding a JWT authentication using LexikJWTAuthenticationBundle](core/jwt.md)
111112
1. [Testing with Swagger](core/jwt.md#testing-with-swagger)
112113
2. [Testing with Behat](core/jwt.md#testing-with-behat)
113-
23. [NelmioApiDocBundle integration](core/nelmio-api-doc.md)
114-
24. [AngularJS Integration](core/angularjs-integration.md)
114+
24. [NelmioApiDocBundle integration](core/nelmio-api-doc.md)
115+
25. [AngularJS Integration](core/angularjs-integration.md)
115116
1. [Restangular](core/angularjs-integration.md#restangular)
116117
2. [ng-admin](core/angularjs-integration.md#ng-admin)
117-
25. [Swagger Support](core/swagger.md)
118+
26. [Swagger Support](core/swagger.md)
118119
1. [Override Swagger documentation](core/swagger.md#override-swagger-documentation)
119-
26. [GraphQL Support](core/graphql.md)
120+
27. [GraphQL Support](core/graphql.md)
120121
1. [Overall View](core/graphql.md#overall-view)
121122
2. [Enabling GraphQL](core/graphql.md#enabling-graphql)
122123
3. [GraphiQL](core/graphql.md#graphiql)
123-
27. [Handling Data Transfer Objects (DTOs)](core/dto.md)
124-
28. [Handling File Upload with VichUploaderBundle](core/file-upload.md)
124+
28. [Handling Data Transfer Objects (DTOs)](core/dto.md)
125+
29. [Handling File Upload with VichUploaderBundle](core/file-upload.md)
125126

126127
## The Schema Generator Component: Generate Data Models from Open Vocabularies
127128

0 commit comments

Comments
 (0)