As anyone who has used koa knows, the onion model is a clever middleware pattern that uses nested functions, which elegantly encapsulates response and request processing in a single middleware
Koa middleware example:
app.use(async (ctx, next) => {
await next();
})
When we process the request, we are splitting it for each request and the minimum focus should be on the request as a whole (Request & Response) rather than splitting the Request and Response of the request in two separate logics
It is better to visualize the causal relationship between request and response directly through the syntax level of the code, rather than through the function call order
For example, using Koa and Axios to implement the same request timing logic.
Koa
app.use(async (ctx, next) => {
const start = Date.now()
await next()
const ms = Date.now() - start
console.log(ms)
})
Axios
let start = 0
axios.interceptors.request.use(function(config){
start = Date.now()
})
axios.interceptors.response.use(function(response){
const ms = Date.now() - start
console.log(ms)
})
In the axios code, we just implement the single logic of timing, but it is forcibly split into two Hooks, and it is not clear from the syntax level alone that they have any relationship, only that an external variable is created to couple them together
As you can see, the Onion Middleware looks cleaner and more logically cohesive than the regular Hooks.
The onion model has a natural advantage in handling Before / After logic, such as vue-router, redux also use this approach, since the onion model can be used for back-end requests, it can also be used for client-side requests
So, an HTTP client based on the onion model is created, and it looks like this.
Resreq
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)
Top comments (1)
That's great idea!