Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update disabling-http-keep-alive.md for server-side only #43374

Merged
merged 5 commits into from Dec 19, 2022

Conversation

longzheng
Copy link
Contributor

fixes #43354

It is not possible to specify an agent on a single fetch() call since the types for fetch come from TypeScript where agent is not supported as an option.

Fixes vercel#43354

It is not possible to specify an `agent` on a single `fetch()` call since the types for `fetch` come from TypeScript where `agent` is not supported as an option.
@ijjk ijjk force-pushed the canary branch 2 times, most recently from e078ebe to 6b863fe Compare December 2, 2022 05:49
@styfle
Copy link
Member

styfle commented Dec 3, 2022

You said it’s not possible with TS types but what about with JS? Are the types wrong?

I also think the behavior is different for Node.js 16 vs 18 because it’s no longer poly filled on 18, it’s native.

@longzheng
Copy link
Contributor Author

longzheng commented Dec 4, 2022

You said it’s not possible with TS types but what about with JS? Are the types wrong?

I also think the behavior is different for Node.js 16 vs 18 because it’s no longer poly filled on 18, it’s native.

The TypeScript lib.dom.d.ts type definition of fetch() is not wrong because the client-side version of fetch() in browsers does not have an option called agent. For client-side usages of fetch(), this is correct.

However because Next.js supports also using fetch() on the server-side (e.g. ingetServerSideProps), this is where it gets complicated.

With Next.js 13 running on Node 18, you're right fetch() is not polyfilled and instead relies on the Node 18's native global.fetch which comes from [undici](https://github.com/nodejs/undici). Undici does not support agent as a [RequestOptions](https://github.com/nodejs/undici/blob/main/docs/api/Dispatcher.md#parameter-requestoptions).

However running on Node <18 Next.js polyfills fetch() on the server-side with node-fetch which does support agent as an option.

So I guess this is a super complex scenario where the type is not sophisticated enough to know if you're running fetch() on the client-side or server-side, and even on the server-side if you're running with node-fetch polyfill or native global.fetch.

I think the TypeScript type definition of fetch() is the lowest common demoninator and is correct for Next.js, but the docs should not imply you can customize agent in a specific fetch request because it is not always possible.

```

To override all `fetch()` calls globally, you can use `next.config.js`:
To disable HTTP Keep-Alive for all `fetch()` calls on the server-side, open `next.config.js` and add the `httpAgentOptions` config:

```js
module.exports = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this uses the same Agent behavior so it probably wont work either on Node.js 18

cc @Ethan-Arrowood who implemented undici and might know more

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on our testing, unfortunately these agent options aren't compatible with undici and there's no equivalent alternative.

We had to intentionally disable Node 18's undici with --no-experimental-fetch

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

undici's fetch accepts dispatcher which fulfills a similar role as agent though it requires undici specific Pool/Agent/etc instead of node's http agent.

@kodiakhq kodiakhq bot merged commit 2f79baf into vercel:canary Dec 19, 2022
@longzheng longzheng deleted the patch-2 branch January 9, 2023 02:30
@tatethurston
Copy link

With Next.js 13 running on Node 18, you're right fetch() is not polyfilled and instead relies on the Node 18's native global.fetch which comes from [undici](https://github.com/nodejs/undici). Undici does not support agent as a [RequestOptions](https://github.com/nodejs/undici/blob/main/docs/api/Dispatcher.md#parameter-requestoptions).

For anyone else that encounters this -- I mistook this as suggesting new behavior in Next 13, when I believe actually any previous version of Next running on Node18 will use undici and not the fetch polyfill:

https://github.com/vercel/next.js/blob/canary/packages/next/src/server/node-polyfill-fetch.ts#L4

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 17, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Docs: Cannot add agent option in fetch() call
4 participants