You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* feat(performance): update Souin setup & enable Cache-Control public in docs
* feat(performance): simplify caddy config
* feat(performance): remove http_cache public directive
* feat(performance): add an example to set Cache-Control per api resource
* feat(performance): remove http_cache public directive for varnish
* Update performance.md
---------
Co-authored-by: Laurent Bientz <[email protected]>
Co-authored-by: Kévin Dunglas <[email protected]>
Copy file name to clipboardExpand all lines: core/performance.md
+54-30Lines changed: 54 additions & 30 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -16,13 +16,13 @@ This means that after the first request, all subsequent requests will not hit th
16
16
from the cache.
17
17
18
18
When a resource is modified, API Platform takes care of purging all responses containing it in the proxy’s
19
-
cache. This ensures that the content served will always be fresh because the cache is purged in real-time. Support for
19
+
cache. This ensures that the content served will always be fresh because the cache is purged in realtime. Support for
20
20
most specific cases such as the invalidation of collections when a document is added or removed or for relationships and
21
21
inverse relations is built-in.
22
22
23
23
### Integrations
24
24
25
-
#### Built-in Caddy HTTP cache
25
+
#### Built-in Caddy HTTP Cache
26
26
27
27
The API Platform distribution relies on the [Caddy web server](https://caddyserver.com) which provides an official HTTP cache module called [cache-handler](https://github.com/caddyserver/cache-handler), that is based on [Souin](https://github.com/darkweak/souin).
28
28
@@ -35,31 +35,37 @@ The integration using the cache handler is quite simple. You just have to update
35
35
+FROM dunglas/frankenphp:latest-builder AS builder
Update your Caddyfile with the following configuration:
61
+
53
62
```caddyfile
54
63
{
55
-
order cache before rewrite
56
-
...
57
-
cache {
58
-
api {
59
-
souin
60
-
}
61
-
}
64
+
cache
65
+
# ...
62
66
}
67
+
68
+
# ...
63
69
```
64
70
This will tell to caddy to use the HTTP cache and activate the tag-based invalidation API. You can refer to the [cache-handler documentation](https://github.com/caddyserver/cache-handler) or the [souin website documentation](https://docs.souin.io) to learn how to configure the HTTP cache server.
65
71
@@ -73,7 +79,25 @@ api_platform:
73
79
urls: [ 'http://caddy/souin-api/souin' ]
74
80
purger: api_platform.http_cache.purger.souin
75
81
```
76
-
And voilà, you have a fully working HTTP cache with it's own invalidation API.
82
+
83
+
Don't forget to set your `Cache-Control` directive to enable caching on your API resource class.
84
+
This can be achieved using the `cacheHeaders` property:
85
+
86
+
```php
87
+
use ApiPlatform\Metadata\ApiResource;
88
+
89
+
#[ApiResource(
90
+
cacheHeaders: [
91
+
'public' => true,
92
+
'max_age' => 60,
93
+
]
94
+
)]
95
+
class Book
96
+
{
97
+
// ...
98
+
}
99
+
```
100
+
And voilà, you have a fully working HTTP cache with an invalidation API.
77
101
78
102
#### Varnish
79
103
@@ -87,7 +111,6 @@ api_platform:
87
111
invalidation:
88
112
enabled: true
89
113
varnish_urls: ['%env(VARNISH_URL)%']
90
-
public: true
91
114
defaults:
92
115
cache_headers:
93
116
max_age: 0
@@ -98,9 +121,9 @@ api_platform:
98
121
## Configuration
99
122
100
123
Support for reverse proxies other than Varnish or Caddy with the HTTP cache module can be added by implementing the `ApiPlatform\HttpCache\PurgerInterface`.
101
-
Three purgers are available, the built-in caddy http cache purger (`api_platform.http_cache.purger.souin`), the http tags (`api_platform.http_cache.purger.varnish.ban`), the surrogate key implementation
124
+
Three purgers are available, the built-in caddy HTTP cache purger (`api_platform.http_cache.purger.souin`), the HTTP tags (`api_platform.http_cache.purger.varnish.ban`), the surrogate key implementation
102
125
(`api_platform.http_cache.purger.varnish.xkey`). You can specify the implementation using the `purger` configuration node,
103
-
for example to use the xkey implementation:
126
+
for example, to use the `xkey` implementation:
104
127
105
128
```yaml
106
129
api_platform:
@@ -125,7 +148,7 @@ to the client](push-relations.md).
125
148
126
149
### Extending Cache-Tags for Invalidation
127
150
128
-
Sometimes you need individual resources like `/me`. To work properly with Varnish, the `Cache-Tags` header needs to be
151
+
Sometimes you need individual resources like `/me`. To work properly, the `Cache-Tags` header needs to be
129
152
augmented with these resources. Here is an example of how this can be done:
130
153
131
154
```php
@@ -175,7 +198,7 @@ use ApiPlatform\Metadata\ApiResource;
175
198
cacheHeaders: [
176
199
'max_age' => 60,
177
200
'shared_max_age' => 120,
178
-
'vary' => ['Authorization', 'Accept-Language']
201
+
'vary' => ['Authorization', 'Accept-Language'],
179
202
]
180
203
)]
181
204
class Book
@@ -201,7 +224,7 @@ use ApiPlatform\Metadata\Get;
201
224
#[Get(
202
225
cacheHeaders: [
203
226
'max_age' => 60,
204
-
'shared_max_age' => 120
227
+
'shared_max_age' => 120,
205
228
]
206
229
)]
207
230
class Book
@@ -217,7 +240,8 @@ API Platform internally uses a [PSR-6](https://www.php-fig.org/psr/psr-6/) cache
217
240
(the default in the API Platform distribution), it automatically enables support for the best cache adapter available.
218
241
219
242
Best performance is achieved using [APCu](https://github.com/krakjoe/apcu). Be sure to have the APCu extension installed
220
-
on your production server. API Platform will automatically use it.
243
+
on your production server (this is the case by default in the Docker image provided by the API Platform distribution).
244
+
API Platform will automatically use it.
221
245
222
246
## Using PPM (PHP-PM)
223
247
@@ -239,12 +263,12 @@ database driver.
239
263
240
264
### Eager Loading
241
265
242
-
By default Doctrine comes with [lazy loading](https://www.doctrine-project.org/projects/doctrine-orm/en/latest/reference/working-with-objects.html#by-lazy-loading) - usually a killer time-saving feature but also a performance killer with large applications.
266
+
By default, Doctrine comes with [lazy loading](https://www.doctrine-project.org/projects/doctrine-orm/en/latest/reference/working-with-objects.html#by-lazy-loading) - usually a killer time-saving feature but also a performance killer with large applications.
243
267
244
268
Fortunately, Doctrine offers another approach to solve this problem: [eager loading](https://www.doctrine-project.org/projects/doctrine-orm/en/current/reference/working-with-objects.html#by-eager-loading).
245
269
This can easily be enabled for a relation: `#[ORM\ManyToOne(fetch: "EAGER")]`.
246
270
247
-
By default in API Platform, we made the choice to force eager loading for all relations, with or without the Doctrine
271
+
By default in API Platform, we chose to force eager loading for all relations, with or without the Doctrine
248
272
`fetch`attribute. Thanks to the eager loading [extension](extensions.md). The `EagerLoadingExtension` will join every
249
273
readable association according to the serialization context. If you want to fetch an association that is not serializable,
250
274
you have to bypass `readable` and `readableLink` by using the `fetchEager` attribute on the property declaration, for example:
@@ -258,7 +282,7 @@ public $foo;
258
282
...
259
283
```
260
284
261
-
> **Warning**: in order to trigger the `EagerLoadingExtension` you must use [Serializer groups](serialization.md) on relations properties.
285
+
> **Warning**: to trigger the `EagerLoadingExtension` you must use [Serializer groups](serialization.md) on relations properties.
262
286
263
287
#### Max Joins
264
288
@@ -278,7 +302,7 @@ can be a good solution to fix this issue.
278
302
279
303
#### Fetch Partial
280
304
281
-
If you want to fetch only partial data according to serialization groups, you can enable `fetch_partial` parameter:
305
+
If you want to fetch only partial data according to serialization groups, you can enable the `fetch_partial` parameter:
282
306
283
307
```yaml
284
308
# api/config/packages/api_platform.yaml
@@ -292,8 +316,8 @@ If enabled, Doctrine ORM entities will not work as expected if any of the other
292
316
293
317
#### Force Eager
294
318
295
-
As mentioned above, by default we force eager loading for all relations. This behaviour can be modified in the
296
-
configuration in order to apply it only on join relations having the `EAGER` fetch mode:
319
+
As mentioned above, by default we force eager loading for all relations. This behavior can be modified in the
320
+
configuration to apply it only on join relations having the `EAGER` fetch mode:
0 commit comments