I am using axios library for making API calls. The endpoint to which I am making the API calls has the following restrictions.
var rules = [
{interval: 1, limit: 5},
{interval: 3600, limit: 1000, precision: 100}
];
I am looking for a rate-limiting, throttling npm that can address this. I have explored rate-limit, quota and node-rate-limiter but they don't seem to get the task done.
npmjs.com/package/rate-limit allows only setting up delay between API calls. I don't want to do this.
npmjs.com/package/quota seems to be a ok ok solution. I will have to write a custom preset like github.com/analog-nico/quota/blob/HEAD/lib/server…
github.com/jhurliman/node-rate-limiter seems to be interesting but again there is no way to handle two rules at the same time. If there was a way to reduce the tokens for two different limiters for every request made it could have been a perfect fit.
Considering that this is a general requirement I was assuming that there would be some standard way of doing this in node. Am I missing something very obvious.
Might I suggest RxJS?
RxJS is not specifically for throttling, but it can definitely do that and so much more. RxJS is a library for doing reactive functional programming, which makes handling complex asynchronous interactions like this much easier.
Example:
class Throttler { /** * A Subject behaves as an event stream. You pump values * into the stream and each value gets pumped through * the pipeline below. */ request$ = new Subject(); constructor() { this.request$ /* Scan keeps track of what request number we're on. */ .scan((acc, url, index) => { const delay = (index < 5) ? (index === 0) ? 0 : 1 : 1000; return { url: url, delay: delay }; }, {}) .flatMap(({ url, delay }) => { /* Timer will delay by the given `delay` and then make the request. */ return Observable.timer(delay) .flatMap(() => Observable.fromPromise( axios.get(url, { responseType: 'json' }) ) ); }) /* subscribe() receives responses as they stream through. */ .subscribe((data) => { console.log(data); }); } makeRequest(url) { this.request$.next(url); // Pumps the URL into the stream. } } const throttler = new Throttler(); /* Will wait 1 ms between calls */ throttler.makeRequest('localhost/whatever'); throttler.makeRequest('localhost/whatever'); throttler.makeRequest('localhost/whatever'); throttler.makeRequest('localhost/whatever'); throttler.makeRequest('localhost/whatever'); /* Will wait 3600 ms between calls hereafter */ throttler.makeRequest('localhost/whatever'); throttler.makeRequest('localhost/whatever'); throttler.makeRequest('localhost/whatever');