@@ -212,6 +212,50 @@ processes by reserving unused tokens.
212
212
$limit->wait();
213
213
} while (!$limit->isAccepted());
214
214
215
+ Exposing the Rate Limiter Status
216
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
217
+
218
+ When using a rate limiter in APIs, it's common to include some standard HTTP
219
+ headers in the response to expose the limit status (e.g. remaining tokens, when
220
+ new tokens will be available, etc.)
221
+
222
+ Use the :class: `Symfony\\ Component\\ RateLimiter\\ RateLimit ` object returned by
223
+ the ``consume() `` method (also available via the ``getRateLimit() `` method of
224
+ the :class: `Symfony\\ Component\\ RateLimiter\\ Reservation ` object returned by the
225
+ ``reserve() `` method) to get the value of those HTTP headers::
226
+
227
+ // src/Controller/ApiController.php
228
+ namespace App\Controller;
229
+
230
+ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
231
+ use Symfony\Component\HttpFoundation\Response;
232
+ use Symfony\Component\RateLimiter\RateLimiter;
233
+
234
+ class ApiController extends AbstractController
235
+ {
236
+ public function index(RateLimiter $anonymousApiLimiter)
237
+ {
238
+ $limiter = $anonymousApiLimiter->create($request->getClientIp());
239
+ $limit = $limiter->consume();
240
+ $headers = [
241
+ 'X-RateLimit-Remaining' => $limit->getRemainingTokens(),
242
+ 'X-RateLimit-Retry-After' => $limit->getRetryAfter()->getTimestamp(),
243
+ 'X-RateLimit-Limit' => $limit->getLimit(),
244
+ ];
245
+
246
+ if (false === $limit->isAccepted()) {
247
+ return new Response(null, Response::HTTP_TOO_MANY_REQUESTS, $headers);
248
+ }
249
+
250
+ // ...
251
+
252
+ $reponse = new Response('...');
253
+ $response->headers->add($headers);
254
+
255
+ return $response;
256
+ }
257
+ }
258
+
215
259
Rate Limiter Storage and Locking
216
260
--------------------------------
217
261
0 commit comments