I use this below code for rate limit using auth user tps and user not is_api when use default rate limit. but sometimes get 429 before exceed max attempts and how to get remaining attempts before exceed attempts for user.
Please share any suggestion that comes to your mind. Your help is much appreciated.
RateLimiter::for('api', function (Request $request) {
$user = $request->user();
if (!empty($user->is_api)) {
$tps = ($user->tps) ? $user->tps : config('api.DEFAULT_TPS');
$key = optional($user)->id ?: $request->ip(); // Use user ID as the key
$meta = [
'user' => [
'id' => $user->id,
'name' => $user->name
]
];
$log = [
request()->_requestId,
'hit',
json_encode([
'meta' => $meta,
'key' => $key,
'tps' => $tps
])
];
Log::channel('request-log')->info(implode(",", $log));
return Limit::perMinute($tps * 60)->by($key)->response(function (Request $request, array $headers) use ($user, $key, $meta) {
$retryAfter = $headers['Retry-After'];
$message = "Too many attempts. Try again after {$retryAfter} times";
$meta = [
'user' => [
'id' => $user->id,
'name' => $user->name
],
'remaining-attempts' => $headers['X-RateLimit-Remaining'],
'headers' => $headers,
'key' => $key,
'message' => $message,
'reason' => 'exception-thrown'
];
$log = [
request()->_requestId,
'failed',
json_encode([
'meta' => $meta
])
];
Log::channel('request-log')->info(implode(",", $log));
return response()->json(['message' => $message], 429);
});
}
return Limit::perMinute(60)->by(optional($user)->id ?: $request->ip());
});