How To Add Rate Limiting to API within an Laravel Application - (r)
-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:
- PHP 8.2, Composer, and Laravel is installed and configured locally on your machine
- A user account on GitHub, GitLab and Bitbucket for pushing your software
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
- To begin, clone the template of the project..
- Then, create a .env file in the project's root directory and copy the contents of .env.example into it.
- 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
.
- 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
.
- Go to the URL and confirm that the Laravel welcome page populates:
Configuring Databases
Set up and configure the database for application in My.
- Go to the My Account dashboard, then click on Add service. "Add service" button:
- On the Add Service list, click "Database" and set the parameters that will start your database instance:
This guide uses MariaDB However, you may pick any of the supported Laravel databases that offer.
- 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.
- Copy and update the database of your app's .env credentials with external credentials as in the screenshot below:
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
- 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.
- 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:
- 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
- Install the Laravel Throttle package by using the following command:
composer require "graham-campbell/throttle:^10.0"
- 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.
- In the beginning, you must create the middleware needed:
php artisan make:middleware RestrictMiddleware
- 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 includeUse 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);
- 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,
];
- 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:
How to throttle requests via IP Address
In the next step, you will rate requests based on the IP address.
- Install this Throttle middleware on the
/book
endpoint'sPATCH
ANDPATCH
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']);
);
- 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.
How To Throttle Based on the User ID and Sessions
- To rate limit using
user_id
andsession
parameters, update theconfigureRateLimiting
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());
);
- Finally, apply this code on the
/book/id GET
andthe /book POST
routes of theroutes/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.
- To test rate-limiting with these strategies, make a middleware app called CustomMiddleware with the below command:
php artisan make:middleware CustomMiddleware
- 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;
- 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);
- 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,
];
- 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.
- 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.
- 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.
- 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.
- 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.
- Finally, the Payment tab provides a list of your selections. Select the payment method you prefer to complete the transaction.
- After that, go to after which click the Application tab to see the list of applications that have been deployed.
- Click the application name for details about its deployment, as shown below. You can use the URL of the application to get it.
How to Test the App
- 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.
- Create a
.htaccess
file in your app's root directory and insert the following code into the file:
RewriteEngine On
RewriteRule ^(. *)$ public/$1 [L]
- Make these changes available on GitHub and auto-deploys to enact the change.
- 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.