How To Add Rate Limiting to API within an Laravel Application - (r)

Aug 15, 2023
Two people learning about laravel throttle

-sidebar-toc>

Limiting the rate of use is essential to protect your website or app resources from excessive or improper usage. Whether a result of malicious human intervention, bot-based attacks, or a missed vulnerability, resource misuse can interfere with legitimate access to your application and introduce severe vulnerability.

This article explains how you can include rate limiting in an API within the Laravel application.

Throttle Your API Traffic in Laravel

The mechanism of rate limiting was that is designed to limit the use of your application's resources. While it has many uses, it is particularly useful for public APIs in huge, high-performance systems. It ensures that all authentic users have equal access to the system's resources.

Limiting the rate of data transfer is essential in terms of security, cost control as well as overall stability of the system. It can help prevent attacks based on requests, like distributed denial of-service (DDoS) attacks. This attack relies on sending repeatedly to overload and cause disruption to access to a website or web server.

There are a variety of methods to setting up rate limits. You can use variables that characterize the requester to determine who can access your application and how frequently. Some common variables include:

  • IP Address The implementation of rate limitations that are based on IP addresses allow users to limit the amount of requests for each address. This is particularly useful in circumstances where users can gain access to an application with no the credentials.
  • API Key The restriction of access via API keys entails offering the user with an API key that has been generated and setting rate limits on a per-key basis. With this approach it's possible to also assign different levels of access to the generated API keys.
  • Client ID -- You can create a Client ID which a user may embed into the header or body of API requests. This allows you to set per-ID access levels to ensure that no one client has the ability to monopolize resource resources of the system.

Laravel Middleware

What is the best way to implement rate limits?

This tutorial utilizes an API for mini libraries that is available built on the Laravel 10 framework to demonstrate how to use Laravel Throttle. The starter project sample contains the basic create read, update and delete (CRUD) implementations required to handle books within an assortment, and also two more methods to illustrate some limitations on rate.

The prerequisites

The guide assumes that you're familiar with the basics of API development using Laravel. Ensure that you have the following skills:

You also utilize the My to set up and launch this API. You can follow along with the supplied project template and then preview the final output from the complete program code.

Laravel Application Set-Up

  1. To begin, clone the template of the project..
  2. Then, create a .env file in the project's root directory and copy the contents of .env.example into it.
  3. After that, finish your setup by following instructions to install the app dependencies and generate the app key.
composer install
 php artisan key:generate

If this command does not automatically add the app key to your .env file, execute the php artisan key:generate command with --show and copy the created key and add it to your .env file as the key value in APP_KEY.

  1. Once the dependencies installation and the application key generation is done, open the application with the following command
php artisan serve

This command starts the application and makes it accessible via the browser at https://127.0.0.1:8000.

  1. Go to the URL and confirm that the Laravel welcome page populates:
The Laravel welcome page displays its logo at the top-center.
The Laravel welcome screen

Configuring Databases

Set up and configure the database for application in My.

  1. Go to the My Account dashboard, then click on Add service. "Add service" button:
The upper segment of the My Dashboard tab features a top toolbar.
My dashboard with several services that I have configured.
  1. On the Add Service list, click "Database" and set the parameters that will start your database instance:
's
My configuration of my database.

This guide uses MariaDB However, you may pick any of the supported Laravel databases that offer.

  1. Once you've completed your database details, click on the Proceed button to finalize the process.

Databases provisioned on have internal and external connection parameters. The best practice is to utilize internal connection parameters to applications hosted within the same account as well as external connection parameters to connect externally. Thus, make use of's external database credentials in your application.

  1. Copy and update the database of your app's .env credentials with external credentials as in the screenshot below:
The  dashboard displays the "Basic details" section of the newly created "library-records" database.All information matches that entered in the previous database setup image.
My database configuration details.
DB_CONNECTION=mysql
 DB_HOST=your_host_name
 DB_PORT=your_port
 DB_DATABASE=your_database_info
 DB_USERNAME=your_username
 DB_PASSWORD=your_password
  1. After entering the credentials for the database, check the connection by applying Database migration with the commands following:
php artisan migrate

If everything functions well, you should get the same response as shown below.

The terminal output displays the "php artisan migrate" Bash command and its output.Immediately below the command, an "INFO" label states "Running migrations."Below this are the four migrations and their statuses, listed as follows:2014_10_12_000000_create_users_table...812ms DONE.2014_10_12_100000_create_password_reset_tokens_table...882ms DONE.2019_08_19_000000_create_failed_jobs_table...942ms DONE.2019_12_14_000001_create_personal_access_tokens_table...1,250ms DONE.Below, the cursor sits on an empty command line to allow additional input.
A successful database migration using a terminal.
  1. Next, use the following option to display all the app routes. You can also see routes that have been implemented.
php artisan route:list

You should now be able to see the API endpoints available:

The terminal displays the "php artisan route:
The route of the application is displayed on the terminal.
  1. Start the application and confirm that everything still works fine. Test these endspoints with a terminal application such as Postman or CURL.

How To Rate Limit within an Laravel Application

  1. Install the Laravel Throttle package by using the following command:
composer require "graham-campbell/throttle:^10.0"
  1. It is also possible to make further changes to the Laravel Throttle configurations through the publication of the vendor configuration file:
php artisan vendor:publish --provider="GrahamCampbell\Throttle\ThrottleServiceProvider"

How to Block IP addresses

One rate-limiting technique lets you block access for a particular set of IP addresses.

  1. In the beginning, you must create the middleware needed:
php artisan make:middleware RestrictMiddleware
  1. Next, open the created app/Http/Middleware/RestrictMiddleware.php middleware file and replace the code in the handle function with the snippet below. Be sure to include Use App to the list of imports at the very top of the middleware file.
$restrictedIps = ['127.0.0.1', '102.129.158.0'];
 if(in_array($request->ip(), $restrictedIps))
 App::abort(403, 'Request forbidden');
 
 return $next($request);
  1. In the     app/Http/Kernel.php    Create an alias to the middleware application by updating the     middlewareAliases    array as follows:
protected $middlewareAliases = [
 . . . 'custom.restrict' => \App\Http\Middleware\RestrictMiddleware::class,
 ];
  1. Then, apply this middleware on the route /restricted in the routes/api.php file as the following and try:
Route::middleware(['custom.restrict'])->group(function () 
 Route::get('/restricted-route', [BookController::class, 'getBooks']);
 );

When working correctly, this middleware blocks all requests from IP addresses in the array: $restrictedIps array. These include 127.0.0.1 and 102.129.158.0. Requests from these IPs return an error code of 403 forbidden response as illustrated below:

The Postman app returns a "403 Request Forbidden" response to a GET request to the URL
A 403 forbidden response to the restricted-route GET endpoint on Postman

How to throttle requests via IP Address

In the next step, you will rate requests based on the IP address.

  1. Install this Throttle middleware on the /book endpoint's PATCH AND PATCH routes. routes/api.php:
Route::middleware(['throttle:minute'])->group(function () 
 Route::get('/book', [BookController::class, 'getBooks']);
 );
 
 Route::middleware(['throttle:5,1'])->group(function () 
 Route::patch('/book', [BookController::class, 'updateBook']);
 );
  1. You must also update the configureRateLimiting function in the app/Providers/RouteServiceProvider file with the middleware you added to the above routes.
... 
 RateLimiter::for('minute', function (Request $request) 
 return Limit::perMinute(5)->by($request->ip());
 );

This limit on requests for the book GET endpoint to 5 minutes, which is shown below.

The Postman app returns a "429 Too Many Requests" response to a GET request to the URL
A "429 Too Many Requests" response to the"/book" GET Endpoint of Postman.

How To Throttle Based on the User ID and Sessions

  1. To rate limit using user_id and session parameters, update the configureRateLimiting function in the app/Providers/RouteServiceProvider file with the following additional limiters and variables:
...
 RateLimiter::for('user', function (Request $request) 
 return Limit::perMinute(10)->by($request->user()?->id ? : $request->ip());
 );
 RateLimiter::for('session', function (Request $request) 
 return Limit::perMinute(15)->by($request->session()->get('key') ? : $request->ip());
 );
  1. Finally, apply this code on the /book/id GET and the /book POST routes of the routes/api.php file:
Route::middleware(['throttle:user'])->group(function () 
 Route::get('/book/id', [BookController::class, 'getBook']);
 );
 Route::middleware(['throttle:session'])->group(function () 
 Route::post('/book', [BookController::class, 'createBook']);
 );

This code limits requests using the user_id as well as session and session.

Other Methods to Throttle

Laravel Throttle features several other methods to provide greater control of your rate-limiting application. These methods include:

  • attempt -- Hits the point at which it reaches, increases the hit count, and returns a boolean that indicates whether the hit limit configured is over.
  • hit -- Hits the Throttle, increases the count of hits and returns $this to enable another (optional) method calling.
  • clear resets the Throttle count back to zero, and then returns $this so you can make another call, if you want to.
  • count -- Returns the total number of hits to the Throttle.
  • check -- Returns an objctan that indicates whether the Throttle hit limit has been over.
  1. To test rate-limiting with these strategies, make a middleware app called CustomMiddleware with the below command:
php artisan make:middleware CustomMiddleware
  1. Then, add the following import files to the newly created middleware file in app/Http/Middleware/CustomMiddleware.php:
use GrahamCampbell\Throttle\Facades\Throttle;
 use App;
  1. After that, change the content within handle method with the following code: Replace handle method by using the code example below:
$throttler = Throttle::get($request, 5, 1);
 Throttle::attempt($request);
 if(!$throttler->check())
 App::abort(429, 'Too many requests');
 
 return $next($request);
  1. In the app/Http/Kernel.php file, set up an alias of this middleware app by making changes to middlewareAliases array. middlewareAliases array in the following manner.
protected $middlewareAliases = [
 . . . 'custom.throttle' => \App\Http\Middleware\CustomMiddleware::class, 
 ];
  1. After that, you can apply this middleware to the custom-route in the routes/api.php file:
Route::middleware(['custom.throttle'])->group(function () 
 Route::get('/custom-route', [BookController::class, 'getBooks']);
 );

The customized middleware that was recently implemented will determine whether the throttle limit has been exceeded by using the check/code method. If the limit has been exceeded it will issue a 429 error. Otherwise, it allows the request to go on.

How to deploy the application to the Server

After you've learned how to implement rate limiting in a Laravel application, make sure you deploy your application to the server in order to make it open to the world.

  1. On your dashboard, select on the "Add Service" button and then choose the application from the menu. Join your Git account to your account and select the correct repository to be deployed.
  2. Under the Basic Details, name the application and select your preferred location for the data center. Also, ensure you added the necessary application environment variables. They are the same as those that are within your personal .env file: the app_key as well as the database configuration variables.
The
The application details are available can be found on My.
  1. Press the Keep button to choose the construct environment variables. You can leave the default values, because the auto-fill feature fills in all necessary parameters.
  2. In the Processes tab, you are able to leave the default values or create a new name for the process. It is also possible to choose the instance and pod sizes on the tab.
  3. Finally, the Payment tab provides a list of your selections. Select the payment method you prefer to complete the transaction.
  4. After that, go to after which click the Application tab to see the list of applications that have been deployed.
  5. Click the application name for details about its deployment, as shown below. You can use the URL of the application to get it.
The My "Deployments" tab displays details about the deployed applications.
Details about deployments on My Dashboard.

How to Test the App

  1. To test the application locally, you can use the php artisan serve command.

This command makes your application browser accessible at http://localhost:8000. You are able to test the API endpoints that you implemented rate limiting from this page by calling repeatedly to trigger the rate limit function.

The server shows the Access Forbidden response because you haven't added configuration details that direct on how to serve the application. Add these details now.

  1. Create a .htaccess file in your app's root directory and insert the following code into the file:

 RewriteEngine On
 RewriteRule ^(. *)$ public/$1 [L]
 
  1. Make these changes available on GitHub and auto-deploys to enact the change.
  2. Open the application using the provided URL and make sure you are on the Laravel welcome page.

You can now check the API endpoints that you implemented rate limiting using Postman through numerous calls until you've reached the configured limit. The response is an error message of 4029: Too many Requests response after exceeding the limit.

Summary

Implementing rate-limiting features into the Laravel API allows you to manage the amount that users use an application's resources. This helps to ensure that your users have a safe and reliable experience without under and over-spending. This also helps ensure that the foundational infrastructure is effective and functional.

Marcia Ramos

I'm the Editorial Team Lead at . I'm a open source enthusiast and love programming. More than seven years of technical writing as well as editing experience in the tech industry, I love collaborating with others to write simple and clear documents and to improve workflows.