UNPKG

lol-js

Version:

Node.js bindings for the Riot API, with caching and rate limiting

105 lines (79 loc) 4.74 kB
Development ----------- Language ======== lol-js is written in [CoffeeScript](http://coffeescript.org/), using the [es6-promise](https://github.com/jakearchibald/es6-promise) Promise polyfill. Testing lol-js =============== Run `npm test` to run unit tests. Tests are executed directly from the CoffeeScript source files, as this makes for better stack traces when things go wrong. Design Overview =============== Calling `lol.client()` will return an instance of the Client class. The core functionality of the `Client` class is defined in `src/client`, however many of the methods on the client class are defined in files located in the `src/api` folder. The Riot API is divided into multiple "child APIs" each with their own version (match, summoner, game, etc...). `src/api` contains one file for each of these child APIs. Each file exports two parameters: ``` api = exports.api = { fullname: "game-v1.3", name: "game", version: "v1.3" } exports.methods = { getRecentGamesForSummoner: pb.break (region, summonerId, options) -> ... } ``` `api` should always be a `{fullname, name, version}` object. The `fullname` is used when generating cache keys, so that results from old APIs won't be retrieved from the cache. If you write a function in one API that calls into a function in another API, it is best practice to [assert](http://nodejs.org/api/assert.html#assert_assert_value_message_assert_ok_value_message) that the other API's version is what you expect it to be; this way when Riot changes an API, we'll be sure to catch all the places where we need to update functions to deal with the changes. The `api` object is also handy for using the `_makeUrl` helper function. `methods` is a hash of functions which will be mixed in to the `Client` class's prototype. These methods can call into methods in the core `Client` class or even into methods defined in other APIs. Methods are generally written to return a Promise, and then passed through promise-breaker's `break` to make them accept an optional callback. Writing API Modules =================== If you are adding a new API module to `src/api`, or updating an existing API, there are three core methods in the `Client` class which you can use to easily implement your API. Note that all of the following return promises. * `Client._riotRequest(params)` makes requests to the Riot API and returns the raw results. `_riotRequest()` doesn't do any caching, but by default enforces rate limits (although you can disable rate limit checks by passing `params.rateLimit` as false - handy for APIs such as lol-static-data where queries do not count against your rate limit.) * `Client._riotRequestWithCache(params, cacheParams, options)` is similar to `_riotRequest()`, but automatically caches results. `params` is identical to the `params` object passed to `_riotRequest()`. `cacheParams` is the params object which will be passed to `cache.get()` and `cache.set()`. See below for more details on `cacheParams`. * There are many Riot APIs where you can pass a comma delimited list of IDs or names in the URL, and get back a hash where keys are IDs and values are the values you want to request. `Client._riotMultiGet(...)` was written to deal with these cases; it caches each value by ID individually. This helps in the case where, for example, you do something like: client.getSummonersById('na', [1,2], ...) client.getSummonersById('na', [1], ...) Here, we've already retrieved summoner 1 and 2 in the first call, so there should be no need to fetch summoner 1 again in the second call. `_riotMultiGet()` takes care of caching this common case automatically. All of the above methods require you to pass a URL to fetch data from. Most (but not all) Riot APIs follow the same pattern for APIs, so you can use the `_makeUrl()` function to generate a URL for you: ``` url = "#{@_makeUrl region, api}/by-summoner/#{summonerId}/recent" ``` ### cacheParams `cacheParams` is a `{key, region, api, ttl, objectType, params}` object which is passed to cache.get and cache.set. Most cache implementations will probably only need the `key`, but some cache implementations (like writing to an SQL database) may want more fine grained control, so we pass this extra data. The key must uniquely identify the resource being retrieved. The usual format is a dash separated string of the format: "#{api.fullname}-#{objectType}-#{region}-#{paramsWithDashes}" Any parameters which we pass up to the Riot API should be in `paramsWithDashes`. The `ttl` should generally be either `@cacheTTL.long` or `@cacheTTL.short`. If you don't pass a `ttl`, it defaults to `@cacheTTL.short`.