@@ -212,6 +212,47 @@ 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
+ That's why the ``consume() `` object returns a :class: `Symfony\\ Component\\ RateLimiter\\ RateLimit `
223
+ object which you can use to get the value of those HTTP headers::
224
+
225
+ // src/Controller/ApiController.php
226
+ namespace App\Controller;
227
+
228
+ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
229
+ use Symfony\Component\HttpFoundation\Response;
230
+ use Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException;
231
+ use Symfony\Component\RateLimiter\RateLimiter;
232
+
233
+ class ApiController extends AbstractController
234
+ {
235
+ public function index(RateLimiter $anonymousApiLimiter)
236
+ {
237
+ $limiter = $anonymousApiLimiter->create($request->getClientIp());
238
+ $limit = $limiter->consume();
239
+ if (false === $limit->isAccepted()) {
240
+ throw new TooManyRequestsHttpException();
241
+ }
242
+
243
+ // ...
244
+
245
+ $reponse = new Response($responseContents);
246
+ $response->headers->add([
247
+ 'X-RateLimit-Remaining' => $limit->getRemainingTokens(),
248
+ 'X-RateLimit-Reset' => $limit->getRetryAfter()->getTimestamp(),
249
+ 'X-RateLimit-Limit' => $limit->getLimit(),
250
+ ]);
251
+
252
+ return $response;
253
+ }
254
+ }
255
+
215
256
Rate Limiter Storage and Locking
216
257
--------------------------------
217
258
0 commit comments