Merge pull request #8560 from backstage/jhaals/adr
ADR: Use node-fetch for data fetching
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
---
|
||||
id: adrs-adr013
|
||||
title: 'ADR013: 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.
|
||||
---
|
||||
|
||||
## Context
|
||||
|
||||
Using multiple HTTP packages for data fetching increases the complexity and the
|
||||
support burden of keeping said package up to date.
|
||||
|
||||
## Decision
|
||||
|
||||
Backend (node) packages should use the `node-fetch` package for HTTP data
|
||||
fetching. Example:
|
||||
|
||||
```ts
|
||||
import fetch from 'node-fetch';
|
||||
import { ResponseError } from '@backstage/errors';
|
||||
|
||||
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).
|
||||
It uses `cross-fetch` internally. Example:
|
||||
|
||||
```ts
|
||||
import { useApi } from '@backstage/core-plugin-api';
|
||||
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 packages such as `axios`,
|
||||
`got` and others. Once we have transitioned to `node-fetch` we will add lint
|
||||
rules to enforce this decision.
|
||||
@@ -287,7 +287,8 @@
|
||||
"architecture-decisions/adrs-adr009",
|
||||
"architecture-decisions/adrs-adr010",
|
||||
"architecture-decisions/adrs-adr011",
|
||||
"architecture-decisions/adrs-adr012"
|
||||
"architecture-decisions/adrs-adr012",
|
||||
"architecture-decisions/adrs-adr013"
|
||||
],
|
||||
"FAQ": ["FAQ"]
|
||||
}
|
||||
|
||||
@@ -186,6 +186,8 @@ nav:
|
||||
- ADR009 - Entity References: 'architecture-decisions/adr009-entity-references.md'
|
||||
- ADR010 - Luxon Date Library: 'architecture-decisions/adr010-luxon-date-library.md'
|
||||
- ADR011 - Plugin Package Structure: 'architecture-decisions/adr011-plugin-package-structure.md'
|
||||
- ADR012 - Plugin Package Structure: 'architecture-decisions/adr012-use-luxon-locale-and-date-presets.md'
|
||||
- ADR013 - Plugin Package Structure: 'architecture-decisions/adr013-use-node-fetch.md'
|
||||
- Support:
|
||||
- Backstage Project Structure: 'support/project-structure.md'
|
||||
- Glossary: glossary.md
|
||||
|
||||
Reference in New Issue
Block a user