PHP code example of artisansdk / ratelimiter

1. Go to this page and download the library: Download artisansdk/ratelimiter library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

artisansdk / ratelimiter example snippets


use ArtisanSdk\RateLimiter\Buckets\Leaky;
use ArtisanSdk\RateLimiter\Contracts\Bucket;

public function register()
{
    $this->app->bind(Bucket::class, Leaky::class);
}

use ArtisanSdk\RateLimiter\Buckets\Evented;
use ArtisanSdk\RateLimiter\Contracts\Bucket;

public function register()
{
    $this->app->bind(Bucket::class, Evented::class);
}

protected $routeMiddleware = [
    // ...
    'throttle' => \ArtisanSdk\RateLimiter\Middleware::class,
];

protected $middlewareGroups = [
    // ...
    'api' => [
        'throttle:60,1',
        'bindings',
    ],
];

use ArtisanSdk\RateLimiter\Contracts\Limiter;
use Illuminate\Contracts\Cache\Repository;
use Illuminate\Support\Facades\Cache;

$this->app->when(Limiter::class)
    ->needs(Repository::class)
    ->give(function(){
        return Cache::driver('redis');
    });

// Use the current user as the resolver (default)
// The following lines are all the same binding
use ArtisanSdk\RateLimiter\Resolvers\User;
Route::middleware('throttle');
Route::middleware('throttle:60,1,1');
Route::middleware('throttle:'.User::class.',60,1,60');

// Add the route to the bucket key to add more granularity
use ArtisanSdk\RateLimiter\Resolvers\Route;
Route::middleware('throttle:'.Route::class.',60,1,60');

// Add a tag to the bucket key to group related resources
use ArtisanSdk\RateLimiter\Resolvers\Tag;
Route::middleware('throttle:'.Tag::class.',foo,60,1,60');

use ArtisanSdk\RateLimiter\Resolvers\User as Resolver;
use Symfony\Component\HttpFoundation\Request;

class UserResourceLimits extends Resolver
{
    protected $max = '50|100'; // 50 drips for guests, 100 drips for users
    protected $rate = '1|10'; // 1 drip per second for guests, 10 drips per second for users
    protected $duration = 3600; // 3600 second (60 minute) timeout
    protected $resource = 'user'; // resource key

    public function __construct(Request $request)
    {
        parent::__construct($request, $this->max, $this->rate, $this->duration);
    }

    public function key(): string
    {
        return parent::key().':'.$this->resource();
    }

    public function resource(): string
    {
        return $this->resource;
    }
}

use App\Http\UserResourceLimits;

Route::middleware('throttle:'.UserResourceLimits::class)
    ->prefix('api/user')
    ->group(function($router){
        $router->get('/', 'UserApi@index');
        $router->get('{id}', 'UserApi@show');
    });

Route::get('/dashboard', 'Dashboard@index');

use ArtisanSdk\RateLimiter\Middleware;
use App\Http\FooBarResolver;

$this->app->when(Middleware::class)
    ->needs('$resolver')
    ->give(function(){
        return FooBarResolver::class;
    });

use ArtisanSdk\RateLimiter\Limiter;
use ArtisanSdk\RateLimiter\Bucket;
use Illuminate\Support\Facades\Cache;

// Configure the limiter to use the default cache driver
// and persist the bucket under the key 'foo' and limit to
// 1 hit per minute or up to the maximum of 10 hits while bursting
$bucket = new Bucket($key = 'foo', $max = 10, $rate = 0.016667);
$limiter = new Limiter(Cache::store(), $bucket);

// Keep popping or queuing jobs until empty or the limit is hit
while(/* some function that gets a job */) {

    // Check that we can proceed with processing
    // This is an abstraction for checking if there's an existing timeout
    // or if the leaky bucket is now overflowing
    if( $limiter->exceeded() ) {

        // Put the bucket in a timeout until it drains
        // or you could use any arbitrary duration (or even allow for overflow)
        $seconds = $bucket->duration();
        $limiter->timeout($seconds);
        break;
    }

    // Execute the job and when the work is done, log a hit
    // Unlike the bucket which allows for multiples drips at a time,
    // a rate limiter usually only allows for a single hit at a time.
    $limiter->hit();
}

// Let the caller know when in seconds to try again
return $limiter->backoff();

$limiter = new Limiter(Cache::store(), new Bucket('foo:bar'));

// or let Laravel handle the cache driver dependencies with
$limiter = app(Limiter::class, ['bucket' => new Bucket('foo:bar')]);

use App\Http\RateLimiter;
use ArtisanSdk\RateLimiter\Contracts\Limiter;

$this->app->bind(Limiter::class, RateLimiter::class);

use ArtisanSdk\RateLimiter\Buckets\Leaky;

$bucket = new Leaky('foo');              // bucket named 'foo' with default capacity and leakage
$bucket = new Leaky('foo', 100, 10);     // bucket holding 100 drips that leaks 10 drips per second
$bucket = new Leaky('foo', 1, 0.016667); // bucket that overflows at more than 1 drip per minute

(new Leaky('foo'))
    ->configure([
        'max' => 100,            // 100 drips capacity
        'rate' => 10,            // leaks 10 drips per second
        'drips' => 50,           // already half full
        'timer' => time() - 10,  // created 10 seconds ago
    ])
    ->fill(10)                   // add 10 more drips
    ->leak()                     // recalculate the bucket's state
    ->toArray();                 // get array representation for persistence

$bucket = (new Leaky('foo'))     // instantiate the same bucket as above
    ->max(100)                   // $bucket->max() would return 100
    ->rate(10)                    // $bucket->rate() would return 10
    ->drips(50)                  // $bucket->drips() would return 50
    ->timer(time() - 10)         // $bucket->timer() would get the time
    ->fill(10)                   // $bucket->remaining() would return 40
    ->leak();                    // $bucket->drips() would return 30

$bucket->isEmpty();              // false
$bucket->isFull();               // false
$bucket->duration();             // 10 seconds till empty again
$bucket->key();                  // string('foo')
$bucket->reset();                // keeps configuration but reset drips and timer

use ArtisanSdk\RateLimiter\Buckets\Evented;
use ArtisanSdk\RateLimiter\Contracts\Bucket;

$this->app->bind(Bucket::class, Evented::class);