bent icon indicating copy to clipboard operation
bent copied to clipboard

query parameters

Open jmls opened this issue 5 years ago • 13 comments

is there an option to pass a json object in to use as query parameters for a get operation ?

jmls avatar Aug 22 '20 14:08 jmls

I'm also interested to know this

davehorton avatar Oct 06 '20 17:10 davehorton

You just pass them in as part of the URL path.

mikeal avatar Oct 06 '20 18:10 mikeal

Would be great to have a query string option.

Kostanos avatar Jan 29 '21 16:01 Kostanos

you can use this:

const objToQuery=obj=>Object.keys(obj).map(key=>`${key}=${obj[key]}`).join('&')

hst-m avatar Jan 29 '21 17:01 hst-m

you forgot about escaping :) for now, I'm using querystring module... Just mentioned here, because multiple other "request" like modules having it integrated already, and would be great to have bent with it too.

Kostanos avatar Jan 29 '21 17:01 Kostanos

if you need escaping then add it in. the point is it is very easy to do, no point adding it to this library which is minimalist on purpose

hst-m avatar Jan 29 '21 18:01 hst-m

I’ve gone back and forth on this one.

One one hand, i hate having to do write this over and over again, but I also can’t think of a great way to add this without complicating things because we already use the object type to represent headers.

When I first wrote this library URL and URLSearchParams was not available in Node.js and now it’s available in all supported versions, so there’s probably something that we can do now that we couldn’t in the past.

mikeal avatar Jan 29 '21 18:01 mikeal

What do people think about this:

  1. We allow you to pass an instance of URLSearchParams that will be appended to the URL (after concatenation if you’re using that feature of bent).
  2. We add bent.qs({ name: value }) that does proper string escaping and returns an instace of URLSearchParams.
  3. Now you can do:
const get = bent(url)
await get(‘/path’, bent.qs({ name: value }))

We can even allow them to be used combinatorially, so you can set default values.

const get = bent(url, bent.qs({ name: default })
await get(‘/path’, bent.qs({ name: value }))

Or if you really want to make it difficult for us:

const get = bent(url, bent.qs({ name: default })
await get(‘/path?name=valueThatWillBeOverwritten’, bent.qs({ name: value }))

We can even force a key ordering when we produce the final URL so that we add some determinism to the queryParam generation that isn’t there by default.

mikeal avatar Jan 29 '21 18:01 mikeal

I was not aware of this URLSearchParams before, so looks like you can just do:

new URLSearchParams(obj).toString()

I think keep it simple and let the user do that themselves, is easy enough. A higher priority would be allowing setting the http method in the bent function https://github.com/mikeal/bent/issues/127

hst-m avatar Jan 29 '21 19:01 hst-m

I think the bent.qs(queryObj) stuff could be a helpful shortcut to clean up the code. The bent async function parameters are in order so not sure how you add that in like your example, need to update the param parsing

await get('/path', bent.qs({ name: value }))

hst-m avatar Jan 29 '21 20:01 hst-m

It’s a little late to go changing the function signature.

I’m actually quite fond of using destructuring this way, i do it a lot in other modules, but it’s a little verbose for bent because the simple usage is already so few characters.

mikeal avatar Jan 30 '21 00:01 mikeal

I think the best thing to do is use bent.body() for the body parameter and bent.query() for query, everything else is auto-detected (url, method, response type, status codes, headers), this allows both functions to have the same signature with all options available and no parameter order requirements

const baseRequest = bent('https://example.com', 'json', {header: value})

await baseRequest('GET', '/path', bent.query(query), {header: value})
await baseRequest('POST', '/path', bent.body(body), {header: value})

hst-m avatar Jan 30 '21 16:01 hst-m

What do people think about this:

  1. We allow you to pass an instance of URLSearchParams that will be appended to the URL (after concatenation if you’re using that feature of bent).

I vote for this one. Currently, I'm using bent like this:

const getJSON = bent('http://XXX/notes?token=' + authToken, 'GET', 'json', 200)

// Later
const queryParams = new URLSearchParams({
  page: pageNum,
}).toString()

const response = await getJSON('&' + queryParams)

Assuming I'm thinking about this correctly, I could dramatically simplify the above code without all of the boiler plate.

bugs181 avatar Mar 13 '21 05:03 bugs181