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

Remove node-fetch #11122

Merged
merged 81 commits into from
Jan 4, 2024
Merged

Remove node-fetch #11122

merged 81 commits into from
Jan 4, 2024

Conversation

amoore108
Copy link
Contributor

@amoore108 amoore108 commented Oct 9, 2023

Overall changes

Removes node-fetch and isomorphic-fetch in favour of using Node 18+ built-in fetch mechanism, provided by undici. Removes the need to do #9611

undici has been added as a dependency as we need its Agent constructor to use our custom certs to authenticate requests.

This aligns the Express and Next.js app to use the same fetch mechanism across both apps, and removes the need to keep node-fetch updated through its transition to ESM.

Code changes

  • Remove node-fetch and isomorphic-fetch and the instances these libraries were imported
  • Consolidate the getAgent function across the Express and Next.js apps
  • Mock Agent and getAgent in tests
  • Refactors the Live page fetch to be more inline with other fetchers that use fetchDataFromBFF

Testing

  1. Pull down this branch locally
  2. Run yarn to install the new dependencies
  3. Run yarn dev
  4. Visit a url with the renderer_env=live flag to ensure it fetches Live data with the certs
  5. Confirm the page loads as expected
  6. Repeat the steps for the Next.js app

Helpful Links

Add Links to useful resources related to this PR if applicable.

Coding Standards

Repository use guidelines

@amoore108 amoore108 marked this pull request as ready for review January 4, 2024 10:07
@pvaliani pvaliani self-requested a review January 4, 2024 10:11
Comment on lines +31 to +52
const caPath = process.env.CA_PATH || '/etc/pki/tls/certs/ca-bundle.crt';
const certChainPath =
process.env.CERT_CHAIN_PATH || '/etc/pki/tls/certs/client.crt';
const keyPath = process.env.KEY_PATH || '/etc/pki/tls/private/client.key';

const [ca, certChain, key] = await loadCerts({
caPath,
certChainPath,
keyPath,
});

return fetch(url, {
dispatcher: new Agent({
connect: {
secureContext: createSecureContext({
cert: certChain,
key,
ca,
}),
},
}),
...options,
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this just a nice refactor or does the new native fetch need this new 'dispatcher' and 'connect' to work ?

Copy link
Contributor Author

@amoore108 amoore108 Jan 4, 2024

Choose a reason for hiding this comment

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

This is a required change as we need to read in the certs async instead of sync. It more closely aligns the pattern we have in our main getCerts file that we use for the application requests.

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe a nitpick but do we need to update the comment on this file that references us using isomorphic-fetch, is the comment still true? Lines 9-11 , they're collapsed so can't comment directly on them 😊

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good spot, shall remove these!

@@ -15,7 +13,7 @@ const fetchMarkup = async (url, assetId) => {
headers: {
'User-Agent': 'Simorgh/ws-web-rendering',
},
timeout: SECONDARY_DATA_TIMEOUT,
signal: AbortSignal.timeout(SECONDARY_DATA_TIMEOUT),
Copy link
Contributor

Choose a reason for hiding this comment

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

I haven't seen signal used before ! Why is it preferred over timeout?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The native version of fetch doesn't have a built-in mechanism for timeout, so we need to use the native AbortSignal functionality provided to do a similar thing for us: https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal/timeout_static

@pvaliani
Copy link
Contributor

pvaliani commented Jan 4, 2024

Nice work man!

Is there a use case for undici in the BFF for potential performance benefits to backend fetching? Especially now that the BFF is running on Node 18. I wonder if there are any parallelisation benefits from its connection pooling that it may bring? i.e Topic page fetching

@amoore108
Copy link
Contributor Author

Nice work man!

Is there a use case for undici in the BFF for potential performance benefits to backend fetching? Especially now that the BFF is running on Node 18. I wonder if there are any parallelisation benefits from its connection pooling that it may bring? i.e Topic page fetching

It would need to be an underlying change to the overall fetch mechanism in the BFF, rather than our module specifically since we import the generic .request() function.

@amoore108 amoore108 merged commit 09281ae into latest Jan 4, 2024
11 checks passed
@amoore108 amoore108 deleted the remove-nodefetch branch January 4, 2024 13:43
amoore108 added a commit that referenced this pull request Jan 5, 2024
amoore108 added a commit that referenced this pull request Jan 5, 2024
amoore108 added a commit that referenced this pull request Jan 8, 2024
This was referenced Feb 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants