Applying Koa's onion model to front-end requests
source link: https://dev.to/molvqingtai/applying-koas-onion-model-to-front-end-requests-356p
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Posted on Mar 24
Applying Koa's onion model to front-end requests
Currently most front-end request libraries use two hooks functions to handle requests and responses, which becomes difficult to maintain when we add too much business logic to the request.
The onion model is a very elegant technique for handling requests and responses, and we have a very mature application for it in node development, so why don't I let the front-end requests change to this way as well?
Here is a simple prototype example:
/**
* Composer
* https://github.com/reduxjs/redux/commit/44dfc39c3f8e5e8b51eeab7c44057da6c1086752
* @param {[fuction]} funcs middleware list
* @return {function} (...args) => f1(f2(f3(...args)))
*/
const compose = (funcs) => funcs.reduce((a, b) => (...args) => a(b(...args)));
// middlewares
const middleware1 = (next) => async (req) => {
console.log("1");
const res = await next(req);
console.log("1");
return res;
};
const middleware2 = (next) => async (req) => {
console.log("2");
const res = await next(req);
console.log("2");
return res;
};
const middleware3 = (next) => async (req) => {
console.log("3");
const res = await next(req);
console.log("3");
return res;
};
/**
* This can be replaced with: fetch, XMLRequest
*/
const adapter = ({ params }) => {
console.log("request");
// mock ruquest
return Promise.resolve(`Hello ${params.username}, I'm mock data.`);
};
/**
* Http method
*/
const get = async (path, params) => {
const dispatch = compose([middleware1, middleware2, middleware3]);
return dispatch(adapter)({ path, params });
};
/**
* Mock login
*/
const login = async () => {
const res = await get("/api/login", { username: "John" });
console.log(res);
};
login();
// --- Login output: ----
/**
* 1
* 2
* 3
* request
* 3
* 2
* 1
* Hello John, I'm mock data.
*/
Enter fullscreen mode
Exit fullscreen mode
Change one request processing to middleware, e.g. error interception, event tracking, refresh token, etc. Each function is a separate middleware, there is no coupling between them, we can easily remove or add a middleware and the code will work fine
We no longer have to split the logic at a request into two separate hooks' methods
I think this is a perfect way to intercept requests, and I've turned this idea into a project
It looks like this:
import Resreq from 'resreq'
const resreq = new Resreq({
baseUrl: 'https://example.com'
})
// Intercepting responses and requests using middleware
resreq.use((next) => async (req) => {
try {
console.log(req) // Request can be changed here
const res = await next(req)
console.log(res) // Response can be changed here
return res
} catch (error) {
console.log(error) // Catch errors here
throw error
}
})
const res = await resreq.get('/api', {
params: { foo: 'bar' }
})
console.log(res.json())
Enter fullscreen mode
Exit fullscreen mode
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK