Kindred
Kindred is a Node.js wrapper with built-in rate-limiting (enforced per region), caching (in-memory and Redis), and parameter checking on top of Riot's League of Legends API.
To get started, run one of the following!
1) yarn add kindred-api
2) npm install --save kindred-api
Refer to Wiki for Documentation and Working Examples!
Currently, I'm changing the format of how methods are presented so that it's much easier
to parse.
Check out SUMMONER-V3 or
STATIC-DATA-V3 to see what I mean.
Table of Contents:
Core Features
- All standard endpoints covered but tournament endpoints.
- Supports both callbacks and promises.
- Rate limiter that is enforced per region and follows retry headers.
- Retries on 429 and >= 500. (Doesn't retry on 404)
- Built-in parameter checks so you can hopefully refer to documentation less! :)
- Built-in caching (in-memory and Redis).
- Customized expiration timers. You can set a timer for each endpoint type. Refer to Caching for more info.
- Designed to be simple but convenient. For example, you can call an exclusively by-id endpoint (such as grabbing the runes of a player) with just the summoner name.
How the Methods Work
All list
and by.xxx
functions will have standard parameters.
Any other method will always take in an object as the first parameter, and an optional callback as the second.
These methods can work with different type of parameters (id (summoner!!!), name, accountId) when applicable.
These functions take in an optional region
and an optional options
parameter (whenever possible) WITHIN the same first parameter. Most of the time, when they're called, they look like this:
Object + Callback Functions
const matchlistConfig = {
name: 'Contractz',
options: {
queue: 420,
champion: 67
}
}
k.Matchlist.get(matchlistConfig, KindredAPI.print)
const runesConfig = {
options: {
locale: 'es_ES',
runeListData: 'stats'
},
region: REGIONS.NORTH_AMERICA
}
k.Static.runes(runesConfig, KindredAPI.print)
const championsConfig = {
options: {
champListData: 'all',
version: '7.9.1'
}
}
k.Static.champions(championsConfig, KindredAPI.print)
const koreaChampListConfig = {
options: {
champListData: 'all'
},
region: REGIONS.KOREA
}
k.Static.champions(koreaChampListConfig)
.then(data => console.log(data))
.catch(error => console.error(error))
const rakanConfig = {
id: 497,
options: {
champData: 'all'
},
region: REGIONS.BRAZIL
}
k.Static.champion(rakanConfig)
.then(data => console.log(data))
.catch(err => console.error(err))
const summonerConfig = {
name: 'Contractz'
}
k.Summoner.get(summonerConfig, KindredAPI.print)
Standard Functions
k.Summoner.by.name('Contractz', KindredAPI.print)
const opts = {
queue: [QUEUES.TEAM_BUILDER_RANKED_SOLO, QUEUES.RANKED_FLEX_SR],
champion: 81
}
k.Matchlist.by.name('Contractz', opts, KindredAPI.print)
Make sure to check out the Wiki
for working, copy-pastable examples.
Quickstart
- Debug on
- Dev key rate limiting per region
- In-memory (JS) cache with default settings on for quick scripts
var KindredAPI = require('kindred-api')
var REGIONS = KindredAPI.REGIONS
var QUEUES = KindredAPI.QUEUE_TYPES
var debug = true
var k = KindredAPI.QuickStart('YOUR_KEY', REGIONS.NORTH_AMERICA, debug)
k.Summoner.get({ id: 32932398 }, KindredAPI.print)
k.Summoner.get({ name: 'Contractz' }, KindredAPI.print)
k.Summoner.by.id(32932398, KindredAPI.print)
k.Summoner.by.name('Contractz', REGIONS.NORTH_AMERICA, KindredAPI.print)
const runesConfig = {
options: {
locale: 'es_ES',
runeListData: 'stats'
},
region: REGIONS.NORTH_AMERICA,
}
k.Static.runes(runesConfig, KindredAPI.print)
var name = 'caaaaaaaaaria'
var region = REGIONS.NORTH_AMERICA
var options = {
queue: [QUEUES.TEAM_BUILDER_RANKED_SOLO, QUEUES.RANKED_FLEX_SR],
champion: 79
}
k.Summoner
.get({ name, region })
.then(data => k.Matchlist.get(
{ accId: data.accountId, options }
)
)
.then(data => console.log(data))
.catch(err => console.error(err))
k.Matchlist
.get({ name, region, options })
.then(data => console.log(data))
.catch(err => console.error(err))
var accId = 47776491
var id = 32932398
k.Matchlist.get({ name }, KindredAPI.print)
k.Matchlist.get({ accId }, KindredAPI.print)
k.Matchlist.get({ id }, KindredAPI.print)
k.Runes.get({ name }, KindredAPI.print)
k.Summoner.runes({ name }, KindredAPI.print)
k.Matchlist.get({ name }, KindredAPI.print)
k.Summoner.matchlist({ name }, KindredAPI.print)
k.Matchlist.recent({ name }, KindredAPI.print)
k.Summoner.matchHistory({ name }, KindredAPI.print)
const koreaChampListConfig = {
options: {
champListData: 'all'
},
region: REGIONS.KOREA
}
k.Static.champions(koreaChampListConfig)
.then(data => console.log(data))
.catch(error => console.error(error))
const rakanConfig = {
id: 497,
options: {
champData: 'all'
},
region: REGIONS.BRAZIL
}
k.Static.champion(rakanConfig)
.then(data => console.log(data))
.catch(err => console.error(err))
k.Static.Champion
.list({ champListData: 'all' }, REGIONS.KOREA)
.then(data => console.log(data))
.catch(error => console.error(error))
k.Static.Champion
.by.id(497, { champData: 'all' })
.then(data => console.log(data))
.catch(error => console.error(err))
Known Issues
Both caches currently (JS in-memory, Redis) are primitive implementations, and can possibly exceed memory limitations.
I haven't had to deal with this in my smaller applications (One Tricks for example) and scripts, but I'm guessing some people might use this library for bigger applications. I can add an LRU cache (and MongoDB) as well as a reset() function or something if people start asking.
One Tricks
is simple, but does take a lot of requests currently (probably 25000~ if nothing's cached).
However, I simply use the cache to store all the summoner information and champion information, grind the stats information, and put the algorithmically-processed data in my database.
The difference between my site and other applications people seem to be working on is everyone seems to be doing some mini-op.gg type of thing which would probably demand a more concrete library with better tools, especially with the deprecation of the Stats endpoint.
Rate Limiter is not as optimized as it should be. (FIXED 2.0.33)
Promises retry on 404.
This is problematic because certain calls such as getCurrentGame, which will hit 404's often, will always retry up to 3 times.
This means it'll send a request, get a 404, and then send three more requests for a total of 3 unnecessary requests.
k.CurrentGame.get({ name: 'Contractz' })