Search code examples
node.jsasync-awaitrate-limitingnpm-request

Limit concurrent requests to API in NodeJS along with Async/Await


I am using Request package in my Nodejs project along with Async/Await functions introduced in Node V.8.x to consume 3rd party API, everything was fine until I come across a restriction from API provider; who has restriction of 10 concurrent requests per second.

I tried with many available NPM packages like rate-limiter etc. but, recently found an article relevant to my issue, which introduces me to qrate package.

I tried to work on this with below code: May be I need to use Callback instead of 'done' and handle it in my 'fetchAPIDetails' -- Any HELP is greatly appreciated. Thank you in advance.

const async = require('async')
const request = require('request-promise')
const qrate = require('qrate')
const q = qrate(worker,1,5)

const worker = async (reqBody, options, done) => {
    const options = { method: 'POST', url: apiURL, body: reqBody, timeout: 5000}
    try{
        const response = await request(options)
        if(response.error){errorHandler(response.error); return {}}
        else {
            const body = response.body // Expecting XML
            console.log(body.toString().slice(200,350))
            return body
        }
        return done
    }
    catch(err){return errorHandler(err)} //errorHandler fn
}

const fetchAPIDetails = async () => {
    const IdArr = [a,b,c] // An array of id, which need to pass in reqBody
    try{
        async.eachLimit(IdArr, 1, async id => {
            const reqBody = await queryBuilder(id) // queryBuilder fn
            q.push(reqBody)
        })

    } catch(err){return errorHandler(err)} //errorHandler fn
}

Solution

  • Thank you everyone, who would have worked on my issue here. However, from my further research I get to know, the concurrency of API requests can be handled directly using NPM-Request package, following this article.

    Here is my code for reference, for anyone who would like achieve the same:

    const request = require('request-promise')
    const Parallel = require('async-parallel')
    
    const queryBuilder = async () => { ... } // Builds my Query body (reqBody)
    const errorHandler = async (error) => { ... } // Handles Error
    const requestHandler = async () => {
        try{
            const response = await request(options)
            console.log(response.toString().slice(200,350))
            return response
        } catch(err){return errorHandler(err)} //errorHandler fn
    }
    
    const fetchAPIDetails = async () => {
        const IdArr = [a,b,c] // An array of id, which need to pass in reqBody
        Parallel.concurrency = 1
        try{
            Parallel.each(IdArr, async id => {
                const reqBody = await queryBuilder(id) // queryBuilder fn
    
            })        
        } catch(err){return errorHandler(err)} //errorHandler fn
     }