The Abominable Fetch
16 February 2019
2 min read
The first question i get is why use Fetch API instead of Axios library. Well there are many post online which do well to show the similarities and differences in both libraries. Well for us what worked will be discussed some other time.
Lets jump to the post.
Current situation
Our fetch calls are long and cumbersome to write.
1await fetch(URL_GOES_HERE, {
2 method: 'GET',
3 mode: 'cors',
4 credentials: 'same-origin',
5 headers: {
6 Authorization: `token ${this.props.user.loggedInUser.token}`,
7 'Accept-Language': language,
8 'Content-Type'] = 'application/json'
9 }
10 }
11);
That's a lot of code to just “GET” from the API. Most of the above boiler plate code is repeated for other similar fetch functions across the app. It was evident that mode, credentials, headers can be abstracted out and shared with other fetch functions.
Improvement
To be able to do this effectively, a createFetch wrapper was created which will pass default values to fetch. This new wrapper fetch was then passed down to app via Context React API.
1context.fetch = createFetch(window.fetch, {
2 baseUrl: context.apiConfig.apiUrl,
3 language: store.getState().intl.locale,
4 authToken: store.getState().user.loggedInUser.token
You might be wondering where does token come even before app is started. So this context is created after appropriate APIs are called just before starting the app.
The createFetch wrapper consists of defaults which will add to the options of fetch function. As mentioned below :
Headers
1let options = {};
2
3// language variable is passed down from createFetch params.
4options.headers[’Accept-Language’] = language;
5
6
7// Since mostly JSON object is returned.
8options.headers[’Content-Type’] = 'application/json’;
9
10
11// authToken variable is passed from createFetch params.
12options.headers.Authorization = `token ${authToken}`;
Mode
1options.mode = "cors";
Credentials
1options.credentials = "same-origin";
All the above options are only alloted if they are not explicitly passed. Concluding the defaults we then return the function as follows:
1fetch(url, options);
End result
1await this.props.fetch(URL_GOES_HERE, {
2 method: "GET",
3});
This resulted in a clean and crisp fetch function. Since it was passed down though context, fetch was accessed via props. However the above function is completely flexible to other values.
The default values can be overridden if required, to bring in different options.