unjs/ufo

Encoding query arrays with `name[]` convention

mathieutu opened this issue · 8 comments

Environment

Node v21.1.0
ofetch@1.3.3

Reproduction

withQuery('http://ufo.test', { q: ['foo','bar'] })

Describe the bug

When using withQuery with an array, the param is duplicated instead of having the array syntax.
ex:

withQuery('http://ufo.test', { q: ['foo','bar'] } )

Expected: http://ufo.test?q[]=foo&q[]=bar
Actual: http://ufo.test?q=foo&q=bar

Additional context

Thanks for you work!

Logs

No response

Potentially duplicate of #41

Indeed. So at least could we add a mention in the doc, or throw/log an error in this case?
I'm using ofetch, I've past an array in query and didn't understand why my Laravel backend had a weird behavior. It's because of ufo not implementing the standard common way to do.

pi0 commented

As you probably know, this is URL standard behavior to duplicate params with same key name:

const p = new URLSearchParams()
p.append('q', 'foo')
p.append('q', 'bar')
console.log(p.toString()) // q=foo&q=bar

But i agree that it is was another common way to encode array params mainly in PHP world to use []. Ideally i like to allow "q[]" is the key.

URL standard encodes the key as well:

const p = new URLSearchParams()
p.append('q[]', 'foo')
p.append('q[]', 'bar')
console.log(p.toString()) // q%5B%5D=foo&q%5B%5D=bar

For ufo, i think we might think about serializing it as q[]=foo&q[]=bar i have to double check standard docs if not encoding [] in the query key is valid tough (which I'm pretty sure is valid). This is something we could fix/add in ufo.


After this i think documenting array encoding in ofetch would be a nice idea when patch arrives, feel free to open an issue or directly draft PR in ofetch for this ❤️

Actually, it already works with a q[] key, so it should be probably enough. I'll send a pr to ufo and ofetch readmes. (and to be honest, I never wondered about the standard way to do that before 😅)

pi0 commented

Amazing! Only i think ufo needs encoding change still 😅 (unless laravel already handles decoding in param names)

import { withQuery } from "ufo";

console.log(
  withQuery("/", {
    "q[]": ["foo", "bar"],
  })
);

outputs

/?q%5B%5D=foo&q%5B%5D=bar
pi0 commented

update: URLSearchParams seems to encode [] in keys too so probably sticking with it to be more compatible with future plans of adopting more natives (#208)