micro-ftch
Wrappers for built-in fetch() enabling killswitch, logging, concurrency limit and other features.
fetch is great, however, its usage in secure environments is complicated. The library makes it simple.
Usage
A standalone file
micro-ftch.js is also available.
npm install micro-ftch
jsr add jsr:@paulmillr/micro-ftch
import { ftch, jsonrpc, replayable } from 'micro-ftch';
let enabled = true;
const net = ftch(fetch, {
isValidRequest: () => enabled,
log: (url, options) => console.log(url, options),
timeout: 5000,
concurrencyLimit: 10,
});
const res = await net('https://example.com');
const rpc = jsonrpc(net, 'http://rpc_node/', {
headers: {},
batchSize: 20,
});
const res1 = await rpc.call('method', 'arg0', 'arg1');
const res2 = await rpc.callNamed('method', { arg0: '0', arg1: '1' });
const replayNet = replayable(net);
const replayRpc = jsonrpc(replayNet, 'http://rpc_node/', { headers: {}, batchSize: 20 });
const replayRes = await replayRpc.call('method', 'arg0', 'arg1');
await net('https://user:pwd@httpbin.org/basic-auth/user/pwd');
There are three wrappers over fetch():
ftch(fetch) - isValidRequest, logging, timeouts, concurrency limits, basic auth
jsonrpc(fetch) - batched JSON-RPC functionality
replayable(fetch) - log & replay network requests without actually calling network code.
ftch
Basic wrapper over fetch().
isValidRequest
When isValidRequest killswitch is enabled, all requests will throw an error.
You can dynamically enable and disable it any any time.
import { ftch } from 'micro-ftch';
let ENABLED = true;
const f = ftch(fetch, { isValidRequest: () => ENABLED });
f('http://localhost');
ENABLED = false;
f('http://localhost');
ENABLED = true;
f('http://localhost');
log
import { ftch } from 'micro-ftch';
const f = ftch(fetch, { log: (url, opts) => console.log('fetching', url, opts) });
f('http://url/');
timeout
import { ftch } from 'micro-ftch';
const f = ftch(fetch);
const res = await f('http://url/', { timeout: 1000 });
const f2 = ftch(fetch, { timeout: 1000 });
const res2 = await f2('http://url/');
concurrencyLimit
Allows to not accidentally hit rate limits or do DoS.
import { ftch } from 'micro-ftch';
const f = ftch(fetch, { concurrencyLimit: 1 });
const res = await Promise.all([f('http://url1/'), f('http://url2/')]);
Basic auth
import { ftch } from 'micro-ftch';
const f = ftch(fetch);
const res = await f('https://user:pwd@httpbin.org/basic-auth/user/pwd');
jsonrpc
Supports batching multiple HTTP requests into one "Batched" JSON RPC HTTP request. Can massively speed-up when servers are single-threaded, has small per-user limits
import { jsonrpc } from 'micro-ftch';
const rpc = jsonrpc(fetch, 'http://rpc_node/', {
headers: {},
batchSize: 20,
});
const res = await rpc.call('method', 'arg0', 'arg1');
const res2 = await rpc.callNamed('method', { arg0: '0', arg1: '1' });
replayable
Small utility to log & replay network requests in tests, without actually calling network code.
import { ftch as createFtch, replayable } from 'micro-ftch';
const ftch = createFtch(fetch);
const replayCapture = replayable(ftch);
await replayCapture('http://url/1');
await replayCapture('http://url/2');
const logs = replayCapture.export();
const replayTest = replayable(ftch, JSON.parse(logs));
await replayTest('http://url/1');
await replayTest('http://url/2');
await replayTest('http://url/3');
const replayTestOffline = replayable(ftch, JSON.parse(logs), {
offline: true,
});
await replayTestOffline('http://url/1');
await replayTestOffline('http://url/2');
await replayTestOffline('http://url/3');
Privacy
ftch() disables referrer by default by setting referrerPolicy: 'no-referrer'.
License
MIT (c) Paul Miller (https://paulmillr.com), see LICENSE file.