Skip to content

Commit da1121d

Browse files
committed
Add docs for data persisters
1 parent 0734d66 commit da1121d

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
@@ -81,11 +81,12 @@
8181
1. [Custom Collection Data Provider](core/data-providers.md#custom-collection-data-provider)
8282
2. [Custom Item Data Provider](core/data-providers.md#custom-item-data-provider)
8383
3. [Injecting the Serializer in an `ItemDataProvider`](core/data-providers.md#injecting-the-serializer-in-an-itemdataprovider)
84-
16. [Extensions](core/extensions.md)
84+
16. [Data Persisters](core/data-persisters.md)
85+
17. [Extensions](core/extensions.md)
8586
1. [Custom Extension](core/extensions.md#custom-extension)
8687
2. [Filter upon the current user](core/extensions.md#example)
87-
17. [Security](core/security.md)
88-
18. [Performance](core/performance.md)
88+
18. [Security](core/security.md)
89+
19. [Performance](core/performance.md)
8990
1. [Enabling the Built-in HTTP Cache Invalidation System](core/performance.md#enabling-the-builtin-http-cache-invalidation-system)
9091
2. [Enabling the Metadata Cache](core/performance.md#enabling-the-metadata-cache)
9192
3. [Using PPM (PHP-PM)](core/performance.md#using-ppm-php-pm)
@@ -97,32 +98,32 @@
9798
3. [Override at Resource and Operation Level](core/performance.md#override-at-resource-and-operation-level)
9899
4. [Disable Eager Loading](core/performance.md#disable-eager-loading)
99100
3. [Partial Pagination](core/performance.md#partial-pagination)
100-
19. [Operation Path Naming](core/operation-path-naming.md)
101+
20. [Operation Path Naming](core/operation-path-naming.md)
101102
1. [Configuration](core/operation-path-naming.md#configuration)
102103
2. [Create a Custom Operation Path Naming](core/operation-path-naming.md#create-a-custom-operation-path-resolver)
103104
1. [Defining the Operation Path Naming](core/operation-path-naming.md#defining-the-operation-path-resolver)
104105
2. [Registering the Service](core/operation-path-naming.md#registering-the-service)
105106
3. [Configure it](core/operation-path-naming.md#configure-it)
106-
20. [Accept application/x-www-form-urlencoded Form Data](core/form-data.md)
107-
21. [FOSUserBundle Integration](core/fosuser-bundle.md)
107+
21. [Accept application/x-www-form-urlencoded Form Data](core/form-data.md)
108+
22. [FOSUserBundle Integration](core/fosuser-bundle.md)
108109
1. [Installing the Bundle](core/fosuser-bundle.md#installing-the-bundle)
109110
2. [Enabling the Bridge](core/fosuser-bundle.md#enabling-the-bridge)
110111
3. [Creating a `User` Entity with Serialization Groups](core/fosuser-bundle.md#creating-a-user-entity-with-serialization-groups)
111-
22. [Adding a JWT authentication using LexikJWTAuthenticationBundle](core/jwt.md)
112+
23. [Adding a JWT authentication using LexikJWTAuthenticationBundle](core/jwt.md)
112113
1. [Testing with Swagger](core/jwt.md#testing-with-swagger)
113114
2. [Testing with Behat](core/jwt.md#testing-with-behat)
114-
23. [NelmioApiDocBundle integration](core/nelmio-api-doc.md)
115-
24. [AngularJS Integration](core/angularjs-integration.md)
115+
24. [NelmioApiDocBundle integration](core/nelmio-api-doc.md)
116+
25. [AngularJS Integration](core/angularjs-integration.md)
116117
1. [Restangular](core/angularjs-integration.md#restangular)
117118
2. [ng-admin](core/angularjs-integration.md#ng-admin)
118-
25. [Swagger Support](core/swagger.md)
119+
26. [Swagger Support](core/swagger.md)
119120
1. [Override Swagger documentation](core/swagger.md#override-swagger-documentation)
120-
26. [GraphQL Support](core/graphql.md)
121+
27. [GraphQL Support](core/graphql.md)
121122
1. [Overall View](core/graphql.md#overall-view)
122123
2. [Enabling GraphQL](core/graphql.md#enabling-graphql)
123124
3. [GraphiQL](core/graphql.md#graphiql)
124-
27. [Handling Data Transfer Objects (DTOs)](core/dto.md)
125-
28. [Handling File Upload with VichUploaderBundle](core/file-upload.md)
125+
28. [Handling Data Transfer Objects (DTOs)](core/dto.md)
126+
29. [Handling File Upload with VichUploaderBundle](core/file-upload.md)
126127

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

0 commit comments

Comments
 (0)