@@ -212,6 +212,50 @@ processes by reserving unused tokens.
212212 $limit->wait();
213213 } while (!$limit->isAccepted());
214214
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+
215259Rate Limiter Storage and Locking
216260--------------------------------
217261
0 commit comments