Skip to content

Commit c249bed

Browse files
authored
Merge pull request #1065 from emberjs/remove-ember-fetch
Deprecate ember-fetch
2 parents 701f62b + 7c7e3c5 commit c249bed

File tree

1 file changed

+151
-0
lines changed

1 file changed

+151
-0
lines changed

text/1065-remove-ember-fetch.md

+151
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
---
2+
stage: accepted
3+
start-date: 2025-01-10T00:00:00.000Z
4+
release-date:
5+
release-versions:
6+
teams: # delete teams that aren't relevant
7+
- cli
8+
- data
9+
- framework
10+
- learning
11+
prs:
12+
accepted: https://github.com/emberjs/rfcs/pull/1065
13+
project-link:
14+
---
15+
16+
<!---
17+
Directions for above:
18+
19+
stage: Leave as is
20+
start-date: Fill in with today's date, 2032-12-01T00:00:00.000Z
21+
release-date: Leave as is
22+
release-versions: Leave as is
23+
teams: Include only the [team(s)](README.md#relevant-teams) for which this RFC applies
24+
prs:
25+
accepted: Fill this in with the URL for the Proposal RFC PR
26+
project-link: Leave as is
27+
-->
28+
29+
# Deprecate and Remove ember-fetch
30+
31+
## Summary
32+
33+
This RFC proposes removing `ember-fetch` from the blueprint for new projects, and recommends alternative, more native, ways of having "managed fetch".
34+
35+
## Motivation
36+
37+
the package, `ember-fetch`, does a fair bit of deceptive and incorrect behavior that is incompatible with modern JavaScript tooling, such as _being_ `ember-fetch`, yet only importing from `fetch`.
38+
39+
## Transition Path
40+
41+
- Remove ember-fetch from all blueprints
42+
- Deprecate the npm package and archieve the github repo.
43+
- Migrate to an alternative for "managed fetch"
44+
45+
### What does `ember-fetch` do?
46+
47+
_primarily_, it wraps the native `fetch` in `waitForPromise` from `@ember/test-waiters` (aka "settled state integration").
48+
49+
50+
secondarily, but not popularly used, are a series of utilities (e.g.: for checking kinds of errors). These could be copied into projects that use them and modified to fit each project's needs.
51+
52+
### Using native `fetch`
53+
54+
If you only use `ember-fetch` in route model-hooks, then the settled-state integration isn't used (or rather, you rely on the routing's settled-state integration, and `ember-fetch`'s settled-state integration is extraneous)
55+
56+
57+
### Direct replacement
58+
59+
60+
To replace `ember-fetch`'s core-functionality using the least amount of effort involves adding a new utility in `@ember/test-waiters`, `waitForFetch`:
61+
62+
```ts
63+
// in @ember/test-waiters
64+
import { waitForPromise } from './wait-for-promise';
65+
66+
export async function waitForFetch<Value>(fetchPromise: Promise<Value>) {
67+
waitForPromise(fetchPromise);
68+
69+
let response = await fetchPromise;
70+
71+
return new Proxy(response, {
72+
get(target, prop, receiver) {
73+
let original = Reflect.get(target, prop, receiver);
74+
75+
if (['json', 'text', 'arrayBuffer', 'blob', 'formData'].includes(prop)) {
76+
return (...args) => {
77+
let parsePromise = original.call(target, ...args);
78+
79+
return waitForPromise(parsePromise);
80+
}
81+
}
82+
83+
return original;
84+
}
85+
});
86+
}
87+
```
88+
89+
90+
To have a single import mirroring the behavior of `ember-fetch`, _in full_, folks can still provide a single export that does:
91+
92+
```ts
93+
import { waitForFetch } from '@ember/test-waiters';
94+
95+
export function wrappedFetch(...args: Parameters<typeof fetch>) {
96+
return waitForFetch(fetch(...args));
97+
}
98+
```
99+
100+
101+
And then throughout your project, you could find and replace all imports of `import fetch from 'ember';` with `import { wrappedFetch } from 'app-name/utils/wrapped-fetch';`
102+
103+
104+
105+
### Using a service
106+
107+
Potentially an easier-to-manage implementation uses a service such as the following:
108+
109+
```ts
110+
import Service from '@ember/service';
111+
import { waitFor } from '@ember/test-waiters';
112+
113+
export default class Fetch extends Service {
114+
115+
@waitFor
116+
@action
117+
requestJson(...args: Parameters<typeof fetch>) {
118+
return fetch(...args).then(response => response.json());
119+
}
120+
121+
@waitFor
122+
@action
123+
requestText(...args: Parameters<typeof fetch>) {
124+
return fetch(...args).then(response => response.text());
125+
}
126+
}
127+
```
128+
129+
### Using warp-drive / ember-data
130+
131+
Docs available on https://github.com/emberjs/data/
132+
133+
## How We Teach This
134+
135+
- Add a deprecation notice to the ember-fetch README
136+
- Archive the ember-fetch repo
137+
- Remove ember-fetch from the blueprints
138+
- Remove ember-fetch from the guides (only one reference per version)
139+
140+
## Drawbacks
141+
142+
- if we keep ember-fetch is not compatible with modern tooling and modern SSR approaches
143+
144+
## Alternatives
145+
146+
- n/a
147+
- ask folks to wrap and proxy fetch themselves
148+
149+
## Unresolved questions
150+
151+
none

0 commit comments

Comments
 (0)