googleapis / googleapis/google-cloud-node

Support deep object notation like Axios

Open
#7,663 0 comments 0 reactions 0 assignees View on GitHub
library: google-cloud-node-core size: m type: feature request
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.