Obmedzenie požiadaviek
Balík pridáva do HTTP klienta Laravelu makro rateLimit() — najrýchlejší spôsob, ako obmedziť odchádzajúce volania:
use Illuminate\Support\Facades\Http;
// Integer shorthand = N requests per minute.
$response = Http::rateLimit(30)->get('https://api.example.com/orders');Keď sa limit dosiahne, middleware počká presne do chvíle, keď je ďalšia požiadavka povolená, znova overí stav a pokračuje — odpoveď jednoducho dostanete o niečo neskôr. (Ak voľné miesto medzitým na zdieľanom úložisku obsadil iný worker, počká znova, namiesto aby limit prekročil.) Iné okno zvolíte odovzdaním RateLimit (vytvoreného fasádou RateLimits) alebo Limit; argument by: priradí limit konkrétnemu vlastníkovi:
use RoundlyConsulting\HttpClientRateLimits\Facades\RateLimits;
Http::rateLimit(RateLimits::perSecond(5))->get('https://api.example.com/things');
Http::rateLimit(RateLimits::perDay(10_000))->get('https://api.example.com/report');
// Each owner gets its own budget (e.g. per account or outbound IP).
Http::rateLimit(30, by: 'acct-1')->get('https://api.example.com/orders');Čo prijíma rateLimit()
use RoundlyConsulting\HttpClientRateLimits\Facades\RateLimits;
use RoundlyConsulting\HttpClientRateLimits\Limit;
Http::rateLimit(30); // int: N requests per minute
Http::rateLimit('github'); // string: named profile from config
Http::rateLimit(RateLimits::perSecond(5)); // a RateLimit
Http::rateLimit(new Limit(maxAttempts: 100, timespan: 'hour')); // a Limit value object
Http::rateLimit([RateLimits::perSecond(5), RateLimits::perMinute(100)]); // compound windows
Http::rateLimit(30, by: 'acct-1'); // any form, scoped to an ownerMiddleware RateLimit priamo
RateLimit je Guzzle middleware, takže ho môžete pripojiť aj cez Http::withMiddleware():
$response = Http::withMiddleware(RateLimits::perSecond(5))
->get('https://api.example.com/things');Vytváranie limitov
Každý limit vzniká cez fasádu RateLimits (pozrite Fasáda RateLimits):
use RoundlyConsulting\HttpClientRateLimits\Facades\RateLimits;
RateLimits::make(Limit $limit); // from a Limit value object
RateLimits::perSecond(int $maxAttempts = 1); // N requests per second
RateLimits::perMinute(int $maxAttempts = 1); // N requests per minute
RateLimits::perHour(int $maxAttempts = 1); // N requests per hour
RateLimits::perDay(int $maxAttempts = 1); // N requests per day
RateLimits::profile(string $name); // a named profile from config
RateLimits::compound(array $limits); // several windows at onceKaždý vrátený RateLimit je fluentný: ->by(), ->alongside(), ->maxWait(), ->jitter(), ->adaptive(), kontrolné metódy ->remaining(), ->availableIn() a ->tooManyAttempts() a tiež ->reset().
Hodnotový objekt Limit
Limit nesie kľúč vlastníka (predvolene global), počet pokusov, okno a príznak trim. Ak potrebujete plnú kontrolu, vytvorte ho priamo a zabaľte cez RateLimits::make(). Menej ako jeden pokus za okno vyhodí InvalidLimitException:
use RoundlyConsulting\HttpClientRateLimits\Facades\RateLimits;
use RoundlyConsulting\HttpClientRateLimits\Limit;
// key (owner), maxAttempts, timespan (Timespan enum or 'second'|'minute'|'hour'|'day'), trim
$limit = new Limit(key: 'acct-1', maxAttempts: 100, timespan: 'hour', trim: true);
$middleware = RateLimits::make($limit);
// Limit is fluent as well:
$limit = (new Limit)->perMinute(30)->by('acct-1')->maxWait(5_000)->jitter(50);Pri zapnutom trim limiter po každej povolenej požiadavke odstráni záznamy staršie ako okno. Každé vstavané úložisko samo odstraňuje záznamy staršie ako deň (s hodinovou rezervou), takže trim je voliteľný — históriu kľúča len skráti na jeho vlastné okno.
Jeden limit na kľúč a okno
Všetky limity, ktoré manager vytvorí, zapisujú pokusy do jedného zdieľaného úložiska pod kľúčom {key}:{window} — napr. github:second. Limity s rovnakým kľúčom aj oknom preto zdieľajú jeden limit bez ohľadu na to, kde vznikli, vrátane samostatných volaní Http::rateLimit(). Predvolený InMemoryStore však platí len v rámci procesu: každý worker vo fronte, PHP-FPM proces či server počíta zvlášť, preto prejdite na zdieľané úložisko (pozrite Úložiská), ak majú z jedného limitu čerpať viaceré procesy:
use RoundlyConsulting\HttpClientRateLimits\Facades\RateLimits;
// Same key + same window = one budget, however and wherever the limit is built.
foreach ($repositories as $repository) {
Http::rateLimit(RateLimits::perSecond(5)->by('github'))
->get("https://api.github.com/repos/{$repository}");
}
// Or build it once and reuse the instance.
$github = RateLimits::perSecond(5)->by('github');
Http::withMiddleware($github)->get('https://api.github.com/user');Obmedzenie ľubovoľného callable
Limiter nie je viazaný na HTTP klienta. Metóda handle() rozloží v čase ľubovoľné callable a vráti jeho výsledok:
use RoundlyConsulting\HttpClientRateLimits\Facades\RateLimits;
$limit = RateLimits::perSecond(10)->by('sdk');
// Pace any callable (an SDK call, a raw Guzzle request, …) through the same limiter.
$result = $limit->handle(fn () => $client->createInvoice($payload));Prejavte lásku k open source
Tento balík je zadarmo pod licenciou MIT. Ak vám šetrí čas, jednorazový príspevok alebo členstvo na Patreone nám pomôže ho ďalej udržiavať, testovať a dokumentovať.
Ďalšie spôsoby podpory vrátane kryptomienOdoslaním daru súhlasíte s našimi podmienkami prijímania darov.
Chcete to zabudovať do svojho produktu?
Naše balíky integrujeme do zákazkových Laravel a AI riešení. Napíšte nám, na čom pracujete, a ozveme sa do 48 hodín.