DEV Community

Cover image for ๐Ÿš€ Protect Your Laravel API: How I Mastered Rate Limiting in a Real Project
Abdullo Akramov
Abdullo Akramov

Posted on

๐Ÿš€ Protect Your Laravel API: How I Mastered Rate Limiting in a Real Project

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 the api key, resetting after 60 seconds.
  • tooManyAttempts: Checks if the limitโ€™s exceeded. RateLimiter::tooManyAttempts('api', 10) returns true 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);
}
Enter fullscreen mode Exit fullscreen mode

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
    });
}
Enter fullscreen mode Exit fullscreen mode

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']);
});
Enter fullscreen mode Exit fullscreen mode

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);
    }
}
Enter fullscreen mode Exit fullscreen mode

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. ๐Ÿš€


๐Ÿ“ข Tags:

Laravel #RateLimiting #PHP #WebDevelopment #API

Top comments (0)