Merge pull request #27925 from backstage/freben/undici

recommend undici
This commit is contained in:
Fredrik Adelöw
2024-11-29 22:09:32 +01:00
committed by GitHub
3 changed files with 86 additions and 1 deletions
@@ -1,10 +1,16 @@
---
id: adrs-adr013
title: 'ADR013: Proper use of HTTP fetching libraries'
title: 'ADR013: [superseded] Proper use of HTTP fetching libraries'
# prettier-ignore
description: Architecture Decision Record (ADR) for the proper use of fetchApiRef, node-fetch, and cross-fetch for data fetching.
---
:::note Superseded
This ADR has been superseded by [ADR014](./adr014-use-fetch.md) and no longer applies.
:::
## Context
Using multiple HTTP packages for data fetching increases the complexity and the
@@ -0,0 +1,78 @@
---
id: adrs-adr014
title: 'ADR014: Proper use of HTTP fetching libraries'
# prettier-ignore
description: Architecture Decision Record (ADR) for the proper use of fetchApiRef, native fetch, and cross-fetch for data fetching.
---
## Context
Until now we have been recommending the use of `node-fetch` in Node.js contexts
through [ADR013](./adr013-use-node-fetch.md). Since then, Backstage has had its
minimum requirements upgraded to Node.js 20 or newer. The Node.js platform has
established a stable, reliable `undici` based native `fetch` in these versions.
Additionally, there are [some issues](https://github.com/backstage/backstage/issues/24590)
with using third party libraries that only appeared in newer versions of
Node.js.
## Decision
All code that is executed in Node.js (including backend and CLIs) should use the
native `fetch` for HTTP data fetching, and `typeof fetch` as the TypeScript type
in code where a `fetch` implementation can be injected or is referred to.
Example:
```ts
import { ResponseError } from '@backstage/errors';
// this is implicitly global.fetch
const response = await fetch('https://example.com/api/v1/users.json');
if (!response.ok) {
throw await ResponseError.fromResponse(response);
}
const users = await response.json();
```
Frontend plugins and packages should prefer to use the
[`fetchApiRef`](https://backstage.io/docs/reference/core-plugin-api.fetchapiref).
```ts
import { useApi } from '@backstage/core-plugin-api';
// Inside some React component...
const { fetch } = useApi(fetchApiRef);
const response = await fetch('https://example.com/api/v1/users.json');
if (!response.ok) {
throw await ResponseError.fromResponse(response);
}
const users = await response.json();
```
Isomorphic packages should have a dependency on the `cross-fetch` package for
mocking and type definitions. Preferably, classes and functions in isomorphic
packages should accept an argument of type `typeof fetch` to let callers supply
their preferred implementation of `fetch`. This lets them adorn the calls with
auth or other information, and track metrics etc, in a cross-platform way.
Example:
```ts
import crossFetch from 'cross-fetch';
export class MyClient {
private readonly fetch: typeof crossFetch;
constructor(options: { fetch?: typeof crossFetch }) {
this.fetch = options.fetch || crossFetch;
}
async users() {
return await this.fetch('https://example.com/api/v1/users.json');
}
}
```
## Consequences
We will gradually transition away from third party `fetch` replacement packages
such as `node-fetch` and others on the Node.js platform.
+1
View File
@@ -227,6 +227,7 @@ nav:
- ADR011 - Plugin Package Structure: 'architecture-decisions/adr011-plugin-package-structure.md'
- ADR012 - Use Luxon Locale: 'architecture-decisions/adr012-use-luxon-locale-and-date-presets.md'
- ADR013 - Use node-fetch: 'architecture-decisions/adr013-use-node-fetch.md'
- ADR014 - Use fetch: 'architecture-decisions/adr014-use-fetch.md'
- FAQ:
- Overview: 'faq/index.md'
- Product FAQ: 'faq/product.md'