Package Exports
- fetch-wrap
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (fetch-wrap) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
fetch-wrap
extend WHATWG fetch API with middleware
- transparent, your extended fetch mantains fetch API
fetch(url, options)
- recursive, extend fetch, extend extended fetch, ...
- use over any fetch implementation you like (native fetch, fetch-ponyfill, fetch-polyfill, etc.)
- pick from built-in middleware and/or write yours
- unit tested and benchmarked against plain fetch
- isomorphic
Install
npm install fetch-wrap --save
Usage
const fetchWrap = require('fetch-wrap');
// you can use native fetch(), or the implementation you prefer
let fetch = require('fetch-ponyfill')();
// extend fetch with a list of wrappers
fetch = fetchWrap(fetch, [
function middleware1(url, options, innerFetch) {
// this middleware does nothing
return innerFetch(url, options);
},
middleware2,
middleware3,
]);
// use your extended fetch
fetch('http://localhost:8080/file.json').then(result => console.log(result));
Built-in Middleware
There's some useful middleware in this package that you can optionally import see src/middleware.js for details, here's a full example:
var fetchWrap = require('fetch-wrap');
var middleware = require('fetch-wrap/middleware');
var fetch = fetchWrap(fetch, [
// support options.params, replace tokens in url and adds query string params
middleware.urlParams({
host: 'localhost'
}),
// apply options based on url (supports wildcards)
middleware.optionsByUrlPattern([
{
for: 'http://localhost*',
options: {
headers: {
Authorization: 'Token 1234'
},
timeouts: {
// will send log events at 2s and 5s with these levels
2: 'warn',
5: 'error' // 5sec timeout from localhost, error!
}
}
}
]),
// automatically serialize body to JSON if needed
middleware.sendJson(),
// automatically parse JSON (revives Dates), optionally send Accept header
// throws on http errors
middleware.receiveJson()
// logs events (start, success, fail, timeouts), defaults to console but supports custom .log handler
middleware.logger()
]);
fetch('http://{host}:8080/test.json', {
params: {
utm_source: 'nodejs'
}
}).then(result => console.log(result));
Write your own Middleware!
const fetchWrap = require('fetchWrap');
fetch = fetchWrap(fetch, [
function(url, options, fetch) {
// modify url or options
return fetch(url.replace(/^(http:)?/, 'https:'), options);
},
function(url, options, fetch) {
// add headers
return fetch(url, fetchWrap.merge({}, options, {
headers: {
Authorization: 'Token 123456'
}
});
}
function(url, options, fetch) {
// modify result
return fetch(url, options).then(function(response) {
if (!response.ok) {
throw new Error(result.status + ' ' + result.statusText);
}
if (/application\/json/.test(result.headers.get('content-type'))) {
return response.json();
}
return response.text();
});
}
function(url, options, fetch) {
// catch errors
return fetch(url, options).catch(function(err) {
console.error(err);
throw err;
});
}
]);
// use your customized fetch!
fetch('http://somedomain.com/news.json').then(function(news) {
// GET https://somedomain.com/news.json with Authorization header, and parsed to json
console.log(news.items);
});
Testing
For unit testing, you can use the built-in testing
middleware to mock or spy fetch calls.
var fetchWrap = require('fetch-wrap');
var middleware = require('fetch-wrap/middleware');
var spyLog = [];
var fetch = fetchWrap(fetch, [
middleware.optionsByUrlPattern([
{
for: 'http://localhost*',
options: {
// mock every request to this url
mock: { name: 'john' }
}
}
])
middleware.testing({
// optional spy function
spy(url, options) {
spyLog.push({ url: url, options: options })
}
})
]);
// it will fail if no `options.mock` is found, to prevent real requests during unit-testing
fetch('http://localhost:8080').then(function(result) {
expect(spyLog[0].url).to.eql('http://localhost:8080');
expect(result).to.eql({ name: 'john' });
})
For details on built-in middleware check src/middleware.js
Benchmark
node src/benchmark
compares fetch (fetch-ponyfill, not extended), with extended fetch (fetch-ponyfill extended with some of the built-in middleware).
Typically results show performance cost is neglectable, example:
fetch GET json x 435 ops/sec ±1.52% (80 runs sampled)
extended fetch GET json x 438 ops/sec ±1.24% (81 runs sampled)