Hey DEV community! 👋 Ever had that moment when you realize your API could get overwhelmed by too many requests? I faced that exact issue in a recent Laravel project and decided to tackle it with Rate Limiting. Spoiler: It worked like a charm! In this post, I’ll break down what Rate Limiting is and show you how I applied it to my project with some handy code snippets. Let’s dive in! 🔒
What Is Rate Limiting? (The Quick Version)
Rate Limiting is like putting a bouncer at your API’s door: “Only 10 requests per minute — everyone else waits!” I needed this in my project to keep things running smoothly.
Why It’s a Game-Changer 🚀
Here’s why I decided to use it:
✅ Security: Stops bots from spamming my API (think brute-force attacks).
✅ Server Health: Keeps my server from choking on too many requests.
✅ Fairness: Ensures all users get a smooth experience, no matter the traffic.
Laravel’s Rate Limiting Superpowers 🦸♂️
Laravel makes Rate Limiting a breeze with some awesome tools. I experimented with two approaches in my project.
Approach 1: The Manual Way with RateLimiter
Laravel’s RateLimiter
facade lets you control limits manually. Here’s what I used:
-
hit
: Tracks each request. Example:RateLimiter::hit('api', 60)
logs a request for theapi
key, resetting after 60 seconds. -
tooManyAttempts
: Checks if the limit’s exceeded.RateLimiter::tooManyAttempts('api', 10)
returnstrue
if there’s more than 10 requests.
Implementation:
$key = 'contacts:' . request()->ip();
RateLimiter::hit($key, 60);
if (RateLimiter::tooManyAttempts($key, 10)) {
$seconds = RateLimiter::availableIn($key);
return response("Whoa! Too many requests. Wait $seconds seconds!", 429);
}
This worked, but I found myself repeating this code everywhere — not ideal. 😅
Approach 2: The Magic of throttle
Middleware ✨
Then I discovered Laravel’s throttle
middleware, and it was a game-changer! I set up a named limit using RateLimiter::for
in RouteServiceProvider:
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Support\Facades\RateLimiter;
protected function configureRateLimiting()
{
RateLimiter::for('contacts', function (Request $request) {
return $request->user()
? Limit::perMinute(20) // 20 for logged-in users
: Limit::perMinute(10)->by($request->ip()); // 10 for others
});
}
Then I applied it to my routes in routes/api.php:
Route::prefix('contacts')->middleware('throttle:contacts')->group(function () {
Route::get('/', [ContactController::class, 'index']);
Route::post('/', [ContactController::class, 'store']);
});
This approach kept my controller clean — no manual checks needed! 😍
My Project: A Contacts API with Rate Limiting 🛡️
For my project, I built a simple API to manage contacts (viewing and adding contacts). I wanted to make sure it could handle traffic without breaking, so I added Rate Limiting.
The Controller
Here’s the controller I used:
namespace App\Http\Controllers;
use App\Models\Contact;
use Illuminate\Http\Request;
class ContactController extends Controller
{
public function index()
{
return response()->json(Contact::all());
}
public function store(Request $request)
{
$validated = $request->validate([
'name' => 'required|string|max:255',
'phone' => 'required|string|max:20',
]);
$contact = Contact::create($validated);
return response()->json($contact, 201);
}
}
Thanks to throttle middleware, I didn’t need to add any Rate Limiting logic here. If users hit the limit, Laravel automatically returns a “429” Too Many Requests response. 🎯
Testing It Out 🔍
I tested it with Postman:
-
Unauthenticated: 10
GET
requests worked fine; the 11th got a “429” error. - With a token (Sanctum): I hit 20 requests smoothly, but the 21st triggered the limit.
It was amazing to see how little code I needed to keep my API safe! 🛡️
Key Takeaways 📌
Using Rate Limiting in my Laravel project was a total win. It’s now a go-to tool for me whenever I build APIs. Here’s what I learned:
✅ Use RateLimiter
for fine-grained control, but throttle
for simplicity.
✅ Protect your server and keep your users happy with just a few lines of code.
Have you tried Rate Limiting in your projects? Drop a comment — I’d love to hear your thoughts! If you want to dive deeper, check out my full setup on Medium. 🚀