node.jsnode-request

NodeJS: Request Library - What is the Proper way to use userQueryString?


Within the Request Documentation it documents the setting "useQuerystring" with the following:

useQuerystring - if true, use querystring to stringify and parse querystrings, otherwise use qs (default: false). Set this option to true if you need arrays to be serialized as foo=bar&foo=baz instead of the default foo[0]=bar&foo[1]=baz.

The API I'm working with needs to send more than one value to the same parameter name; which this setting seems to state can be done when utilizing useQueryString, but I can't seem to figure out where/how to pass the query string so its processed properly and what format to do it within.

e.g. I've tried a number of different places for the Query String in the following code:

let options = {
    uri: "https://api.mysite.com"[0],
    headers: {
        'Authorization': 'Bearer TOKEN_VALUE'
    },
    json: true,
    useQuerystring: true,
    querystring: "foo=bar&foo=baz",
    qs: "foo=bar&foo=baz",
    proxy: "http://localhost:8080",
    strictSSL: false,

};

request.get(options);

When I pass the querystring in the option "querystring", it ignores it (Aka, it seems to be the wrong spot). When I put it in the "normal" spot of "qs"; I end up with a URL of the following that is sent to the server:

"?0=f&1=o&2=o&3=%3D&4=b&5=a&6=r&7=%26&8=f&9=o&10=o&11=%3D&12=b&13=a&14=z"

What is the proper way to pass the query string when using useQuerystring set to true?

Based on the following file it looks like it doesn't change the place of the querystring, so I would think it was qs; but as noted above that doesn't work: https://github.com/request/request/blob/master/lib/querystring.js

Thanks for your help!


Solution

  • The wording in the docs is a little misleading.

    When it says use querystring, it means that the request module will use the querystring module to build your qs parameter as a query string. Or that you can use querystring.parse(...) to parse a query string to an object, and then pass that object to the qs parameter.

    I believe this is the correct usage for what you're trying to do:

    const req = require('request');
    
    const opts = {
        foo: 'bar',
        bar: 'foo',
        arr: ['foo', 'bar', 'etc']
    };
    
    const apiOptions = {
        uri: 'http://testyurl.com',
        headers: {},
        json: true,
        useQuerystring: true,
        qs: opts
    };
    
    req.get(apiOptions);
    
    //This yields: http://testyurl.com/?foo=bar&bar=foo&arr=foo&arr=bar&arr=etc
    

    Failing to set the useQuerystring: true parameter will yield something weird like you've seen:

    http://testyurl.com/?foo=bar&bar=foo&arr%5B0%5D=foo&arr%5B1%5D=bar&arr%5B2%5D=etc
    

    Because request is trying to escape the arr[0], arr[1], and arr[2] in the url.

    Also an option:

    const opts = {
        foo: 'bar',
        bar: 'foo',
        arr: ['foo', 'bar', 'etc']
    };
    
    const querystring = require('querystring');
    const uri = 'http://testyurl.com' + querystring.stringify(opts);
    
    // yields: http://testyurl.comfoo=bar&bar=foo&arr=foo&arr=bar&arr=etc