@callum.boase/fetch
v1.5.0
Published
Wrappers for fetch api
Downloads
50
Readme
_fetch
This is a wrapper for the native browser fetch API, and also works in server-side environment.
Key features:
- Makes fetch API error handling more intuitive
- Recursive retry of failed requests up to a specified number of tries
- Provides a method for executing a string of requests, each with auto-retry, and reporting on the final results
Installation for browser
This package is primarily useful for the browser, since it is a lightweight wrapper for native fetch API.
Simple load the file _fetch.js into your library. Available from CDNJS in this format (replace X.X.X with the desired NPM version):
https://cdn.jsdelivr.net/npm/@callum.boase/[email protected]/browser.js
Usually, you'll want to load it via a script tag (replace X.X.X with desired NPM version):
<script src="https://cdn.jsdelivr.net/npm/@callum.boase/[email protected]/_fetch.js"></script>
Installation for NodeJS
_fetch can be used in NodeJS environment, with the help of it's dependency node-fetch, which functions the same as the browser's fetch API. This means that your code can be used in the same way in browser and server environments.
Installing into NodeJS:
$ npm install @callum.boase/fetch --save
Then just require it into your server-side code
const _fetch = require('@callum.boase/fetch');
Usage
_fetch.one()
Make a single http request.
This function uses the fetch API with additional functionality:
- Automatically consider successful http responses with unsuccessful codes (eg code 429) as errors
- Builds more useful error object
- Auto-retry failed requests (based on default settings or yours specified settings) before returning an error
Parameters for calling _fetch.one()
| Parameter | Type | Required? | Details |
| --- | --- | --- | --- |
| url | string | Yes | Identical to native fetch API URL parameter |
| options | object | No | Identical to the native fetch API options object. Defaults to method: 'GET' if not specified |
| retries | number (>=0) | No | Number of times to retry failed requests. Defaults to 5 if not specified |
| retryDelay | function or number (>=0) | No | Length in milliseconds to wait between attempts at the http request. Either a static number that applies to all requests, or a function that returns a number. Defaults to 1000ms delay for http response codes >= 500, and exponential backoff (1000, 2000, 4000 etc) for http response code 429. if passing retryDelay a function it looks like this: retryDelay(attempts, mostRecentErr)
The arguments passed to the function on invocation are :attempt: (number) the attempt number for this http requestmostRecentErr: (error object) the error object of the most recent error (http response code accessible via mostRecenterr.details.response.status) |
| retryOn | function | No | a function returning true or false. If no function is passed it defaults to retrying only on response codes >= 500 and response cod 429. Arguments passed to this function are: attempt: (number) the attempt at this http requesterr: (error object) the error that occured on this latest http request (http response code accessible via mostRecenterr.details.response.status) |
| helperData | any | No | Any arbritrary data you want to return with the response of this http request |
Basic usage
get request using all default settings
try {
const res = await _fetch.one({
url: 'https://httpstat.us/200',
});
console.log(res);
} catch (err) {
}
advanced request using all default settings
try {
const res = await _fetch.one({
url: 'https:httpstat.us/200',
options: {
method: 'POST',
body: JSON.stringify({data: 'XXX'}),
headers: {"API-Key": '12341234', "Content-Type": "application/json"}
},
helperData: {//any arbritrary data to return with the response of this request
something: 'useful'
}
});
console.log(res);
} catch (err) {
}
varying the default settings
try {
const res = await _fetch.one({
url: 'https://httpstat.us/200',
retries: 4,
retryDelay: function(attempt, mostRecentErr){
if(mostRecentErr.details.response.status >= 400){
return _fetch.tools.exponentialBackoff(attempt);
} else {
return 1000;
}
},
retryOn: function(attempt, err){
if(err.details.response.status >= 400){
return true;
} else {
return false;
}
}
});
} catch (err) {
}
_fetch.many()
Full information coming soon....
_fetch.many() lets you run a series of _fetch.one() requests, each request with auto-retry and the same options and behaviour as _fetch.one();
You pass _fetch.many() an array of requests identical to a single request you would use to call _fetch.one() (see above)
Example:
try {
const requests = [
{url: 'https://npmjs.com/1', retries: 10},//Try this one up to 10 times
{url: 'https://npmjs.com/2'},//Ommitting the retries parameter makes it use default tries
{url: 'https://npmjs.com/3'},
{//Advanced requests are possible as for _fetch.one()
url: 'https://npmjs.com/4',
options: {
method: 'POST',
body: JSON.stringify({data: 'XXX'})
},
helperdata: {something: 'useful'}
},
]
const responses = await _fetch.many({
requests,
delayMs: 1000,//1000ms delay between the sending of each request
progressCbs: [//One or more callback functions, called each time a request finishes (after all retries)
function(progress, len, fetchResult){console.log(progress, len, fetchResult)},
function(progress, len, fetchResult){console.log('something else')}
]
});
console.log(responses);
if(responses.summary.rejected > 0){
throw new Error('At least one request failed');
}
} catch (err) {
}
Tools
Exponential backoff
A handy function for calculating exponential backoff amount via attempt number This can be used if writing your own retryDelay() function to pass to _fetch.one()
var delayMs = _fetch.tools.exponentialBackoff(1)//Returns 1000
var delayMs = _fetch.tools.exponentialBackoff(2)//Returns 2000
var delayMs = _fetch.tools.exponentialBackoff(3)//Returns 4000
//etc