Riot Rate Limiter
Node.JS Rate Limiter for Riot Games API
Features
- 100% Endpoint coverage
- Spread based rate-limiter
- Request synchronization
- Request prioritization
- 429 response retrying
- Concurrent requests
- 429 Retry limit
- Multi-instance / Cluster support
- Built specifically for Riot Games Rate Limiting
Contents
Installation
$ npm install @fightmegg/riot-rate-limiter
Usage
import { RiotRateLimiter } from "@fightmegg/riot-rate-limiter";
const limiter = new RiotRateLimiter();
// async await
const response = await limiter.execute({
url: "https://euw1.api.riotgames.com/lol/some/method",
options: {
headers: {
"X-Riot-Token": "...",
},
},
});
// Promises
limiter
.execute({
url: "https://euw1.api.riotgames.com/lol/some/method",
options: {
headers: {
"X-Riot-Token": "...",
},
},
})
.then((response) => {
// ...
});
API
constructor
new RiotRateLimiter({
debug: boolean = false,
concurrency: number = 1,
retryAfterDefault: number = 5000,
retryCount: number = 4,
datastore: 'local' | 'ioredis' = 'local'
redis?: RedisConnectionOptions | RedisConnectionString = null
});
.execute
This library uses node-fetch underneath the hood for making requests. The .execute
method literally passes everything given to node-fetch, therefore you can change things like method, headers etc..
Any responses that are not 2xx or 429 will be thrown, and must be caught.
We will auto-retry 429
responses, up until the retryCount limit is hit (defaults to 4
), utilising the Retry-After
header to respect the API.
limiter.execute({
url: RequestInfo,
options: RequestInit,
},
jobOptions?: Bottleneck.JobOptions
);
The second argument is optional, which allows you to specify JobOptions such as job priority and unique ID for log identification. The weight of a job cannot be changed from the value of 1
no matter what you pass in.
.rateLimiters
This is a map of all of the rate-limiters created, we create at least 1 rate-limiter for the region of the request, and then at least 1 rate-limiter per method underneath that region.
We use the library Bottleneck as our rate-limiter, which supports chaining rate-limiters, meaning that the parents rate-limiter is always respected by its children.
You can access the region rate-limiters via: limiter.rateLimiters[region].main
and you can access the method rate-limiters via: limiter.rateLimiters[region][method].main
Helpers
We also provided some helper functions & objects.
extractRegion
This can extract the region or platformId from your URL:
import { extractRegion } from "@fightmegg/riot-rate-limiter";
extractRegion("https://na1.api.riotgames.com/method"); // returns na1
extractMethod
This can extract the method from your URL:
import { extractMethod } from "@fightmegg/riot-rate-limiter";
extractMethod(
"https://na1.api.riotgames.com/lol/champion-mastery/v4/scores/by-summoner/12345"
); // returns 'CHAMPION_MASTERY.GET_CHAMPION_MASTERY_SCORE'
METHODS & HOST
For those looking to build a RiotGamesAPI
library ontop of this rate limiter, we export two object called METHODS & HOST. You can use these exports to create the URLs for you, as seen below:
import { compile } from "path-to-regexp";
import { HOST, METHODS } from "@fightmegg/riot-rate-limiter";
const createHost = compile(HOST, { encode: encodeURIComponent });
const createPath = compile(METHODS.ACCOUNT.GET_BY_PUUID, {
encode: encodeURIComponent,
});
const url = `https://${createHost({ platformId: "euw1" })}${createPath({
puuid: "12345",
})}`;
Debugging
If you want to see want the rate-limiter is currently doing, we use the debug module for logging. Simply run your app with:
DEBUG=riotratelimiter* node ...
Testing
Unit tests: npm test
E2E tests: npm run test:e2e