首页 > 解决方案 > 在请求过多后限制 429 秒的 API

问题描述

我正在尝试向BoardGameGeek (BGG) API发出多个请求,在特定时间范围内发出一定数量的请求后,我超时(状态代码 429)。我已经尝试了几个库来尝试让它工作。

我试过使用下面的simple-rate-limiter库,但这没有用,因为 BGG 似乎对他们的速率限制非常激进,而且他们也没有发布官方限制。

    /* simple-rate-limiter initialization (https://www.npmjs.com/package/simple-rate-limiter) */
    const limit = require('simple-rate-limiter');
    const request = limit(require('request')).to(10).per(1000);

    const fetchStatistics = async (game) => {
        /* Fetching the statistics from a separate API, because the base API doesn't include stats */
        const url = 'https://cors-anywhere.herokuapp.com/https://www.boardgamegeek.com/xmlapi2/thing?id=' + game.$.objectid + '&stats=1';
        request(url, (err, res, body) => { // simple-rate-limiter making the request
            const xml = body;
            return XML2JS.parseString(xml, (err, result) => { //XML2JS library call
                console.log(result);
            })
        })
    }

然后我尝试将oibackoff库与 simple-rate-limiter 结合使用,如下所示,但仍然没有运气。

    /* simple-rate-limiter initialization (https://www.npmjs.com/package/simple-rate-limiter) */
    const limit = require('simple-rate-limiter');
    const request = limit(require('request')).to(10).per(1000);

    /* oibackoff initialization (https://www.npmjs.com/package/oibackoff) */
    const backoff = require('oibackoff').backoff({
        algorithm: 'exponential',
        delayRatio: 1,
        maxTries: 0,
    });

    const fetchStatistics = async (game) => {
        /* Fetching the statistics from a separate API, because the base API doesn't include stats */
        const url = 'https://cors-anywhere.herokuapp.com/https://www.boardgamegeek.com/xmlapi2/thing?id=' + game.$.objectid + '&stats=1';

        backoff(request, url, (err, res, body) => { // simple-rate-limiter making the request
            console.log(res.statusCode);
            const xml = res.body;
            return XML2JS.parseString(xml, (err, result) => {
                console.log(result);
            })
        })
    }

难道我做错了什么?我应该使用不同的库/方法吗?


旁注:我也尝试过request-rate-limiter,但我无法让语法与我的项目一起使用。

标签: javascriptreactjsthrottlingrate-limiting

解决方案


此解决方案专门针对BoardGameGeek API

因此,不要做一堆单独的请求,例如:
/xmlapi2/thing?stats=1&id=188920
/xmlapi2/thing?stats=1&id=174476

您可以将它们全部批处理到一个请求中,如下所示:
/xmlapi2/thing?stats=1&id=188920,174476

这意味着您只发送 1 个请求,并且不会受到速率限制。
我确实发现如果您附加超过 1200 个游戏 ID,这仍然会失败。服务器以 响应414 Request-URI Too Large
这是该错误的示例

如果您需要超过 1200 个,那么您可能必须拆分游戏 ID 并发出多个请求,以便一次只请求 1200 个。


推荐阅读