-
Notifications
You must be signed in to change notification settings - Fork 8
Description
What would you like to see in the library?
I phrase this as a feature request, not a bug, because Gaxios only claims to be Axios-like and clearly states that query params are passed to URLSearchParams.
This feature request is to support deep object notation in the same way that Axios does. While there is no formal specification for deep object notation (also known as nested objects) it is widely used, such as Express (qs), PHP, etc.
Axios supports deep object notation. Here is an example test that could be added to Axios that passes:
it("should support deep object notation", function (done) {
axios.get("/foo", {
params: {
foo: {
bar: "baz",
},
},
});
getAjaxRequest().then(function (request) {
expect(request.url).toBe("/foo?foo%5Bbar%5D=baz");
done();
});
});A similar test would fail in Gaxios, for example if you add the following test to test/test.getch.ts:
it('should support deep object notation parameters', async () => {
const opts = {
url,
params: {starfleet: {james: 'kirk', montgomery: 'scott'}},
};
const qs = '?starfleet[james]=kirk&starfleet[montgomery]=scott';
const path = `/${qs}`;
const scope = nock(url).get(path).reply(200, {});
const res = await request(opts);
assert.strictEqual(res.status, 200);
assert.strictEqual(
res.config.url?.toString(),
new URL(url + qs).toString(),
);
scope.done();
});This test fails. Because the config.params is passed to URLSearchParams (see code) it gets clobbered. As a quick example run:
for (const [key, value] of new URLSearchParams({ foo: { bar: 'baz' }})) { console.log(key, value) }And you'll get foo [object Object].
As best I can tell Axios uses its own deep object serialization leveraging JavaScript's FormData. Look at https://github.com/axios/axios/blob/v1.x/lib/helpers/AxiosURLSearchParams.js#L29.
So, if Gaxios were to support deep object notation it may be best to follow a similar approach to Axios given the issues qs may cause, see also #759.
Why wouldn't Gaxios support this? I think OAI/OpenAPI-Specification#1706 (comment) offers good reflection on the challenges here, namely that there are many serialization approaches that could be desired, deep object notation (which again isn't a formal standard) is just one of them.
Perhaps this feature request, then, is to offer an out-of-the-box option to have query string serialization be compatible with Axios. This allows implementers to use Gaxios as a drop-in replacement for Axios when deep object notation is used.
Describe alternatives you've considered
The concept of a workaround to this can be seen here using qs:
if (config?.params) {
const queryString = qs.stringify(config.params, { encode: false });
config.params = qs.parse(queryString, { depth: 0 });
}Additional context/notes
No response
Edit: fix whitespace