Closed chimon2000 closed 6 years ago
@chimon2000 There is actually a pretty easy way to replicate middlewares with wretch
using polyfills
:
EDIT : I improved the code samples in the linked commit, below is a really naïve cache implementation
/* A polyfill function can be used as a middleware like this. */
// Polyfill signature
// (url: the url, options: standard fetch options) => a fetch response
// Middleware signature
// (... middleware options, next: the next middleware to call or global fetch to end the chain) => Polyfill
/* A simple delay */
const delayFetch = (delay, next = fetch) => (url, opts) => {
return new Promise(res => setTimeout(() => res(next(url, opts)), delay))
}
/* Returns the url and method without performing an actual request */
const shortCircuit = (next = fetch) => (url, opts) => {
const response = new Response()
response.text = () => Promise.resolve(opts.method + "@" + url)
response.json = () => Promise.resolve({ url, method: opts.method })
return Promise.resolve(response)
}
/* Logs all requests */
const logFetch = (next = fetch) => (url, opts) => {
console.log(opts.method + "@" + url)
return next(url, opts)
}
/* A throttling cache */
const cache = new Map()
let doThrottle = false
const cacheFetch = (throttle = 0, next = fetch) => (url, opts) => {
const key = opts.method + "@" + url
if(cache.has(key) && !opts.noCache && doThrottle) {
return Promise.resolve(cache.get(key))
}
if(throttle && !doThrottle) {
doThrottle = true
setTimeout(() => { doThrottle = false }, throttle)
}
const monkeyPatch = (response, method) => {
const methodRef = response[method]
response[method] = () =>
methodRef.call(response).then(data => {
cache.get(key)[method] = () => Promise.resolve(data)
return data
})
}
return next(url, opts).then(_ => {
cache.set(key, _.clone());
[ "text", "json", "formData", "blob" ].forEach(method => monkeyPatch(_, method))
return _
})
}
// Just use the "middleware" as a polyfill
wretch().polyfills({
fetch: cacheFetch(1000)
})
// You can even chain them
wretch().polyfills({
fetch: logFetch(delayFetch(1000, shortCircuit()))
})
I'm thinking about adding this code sample to the doc. to explain the logic !
Ah also I forgot to mention that fetch already has a built in cache control (if needed) : https://hacks.mozilla.org/2016/03/referrer-and-cache-control-apis-for-fetch/
@chimon2000 Finally after thinking about it all day I ended up adding a little helper function which should ease things up !
I won't add the middlewares themselves to the wretch codebase to preserve the small size, but feel free to post them in separate repos if you want (like the throttling cache example).
Awesome! I like the idea of keeping the library small and having them as middleware.
Taking some inspiration from axios. It would be nice to have middleware for caching and throttling requests.