googleapis / googleapis/google-cloud-node
Support deep object notation like Axios
- Dominant language
- TypeScript
- Stars
- 3.2k
- Forks
- 712
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 99
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:
```js
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`:
```js
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](https://github.com/googleapis/gaxios/blob/main/src/gaxios.ts#L433-L435)) it gets clobbered. As a quick example run:
```js
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](https://developer.mozilla.org/en-US/docs/Web/API/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 https://github.com/googleapis/google-cloud-node/issues/7705.
Why wouldn't Gaxios support this? I think https://github.com/OAI/OpenAPI-Specification/issues/1706#issuecomment-2704374644 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`:
```js
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
Contributor guide
Assessment
This issue has not been assessed yet.