Middleware functions are functions that have access to the context object and the next middleware function in the application’s request-response cycle. These functions are used to modify the request and response objects for tasks such as parsing request bodies, adding response headers, etc. Koa goes a step further by yielding 'downstream', then flowing the control back 'upstream'. This effect is called cascading.
Following is a simple example of a middleware function in action.
var koa = require('koa'); var app = koa(); var _ = router(); //Simple request time logger app.use(function* (next) { console.log("A new request received at " + Date.now()); //This function call is very important. It tells that more processing is //required for the current request and is in the next middleware function/route handler. yield next; }); app.listen(3000);
The above middleware is called for every request on the server. Thus after every request, we will get the following message in the console.
A new request received at 1467267512545
To restrict it to a specific route (and all its subroutes), we just need to create the routes like we did for routing. Actually its these middleware only that handle our request.
For example,
var koa = require('koa'); var router = require('koa-router'); var app = koa(); var _ = router(); //Simple request time logger _.get('/request/*', function* (next) { console.log("A new request received at " + Date.now()); yield next; }); app.use(_.routes()); app.listen(3000);
Now whenever you request any subroute of '/request', only then it'll log the time.
One of the most important things about middleware in Koa is that the order in which they are written/included in your file, are the order in which they are executed downstream. As soon as we hit a yield statement in a middleware, it switches to the next middleware in line, till we reach the last. Then again we start moving back up and resuming functions from yield statements.
For example, in the following code snippet, the first function executes first till yield, then the second middleware till yield, then the third. As we have no more middleware here, we start moving back up, executing in a reverse order, i.e., third, second, first. This example summarizes how to use middleware the Koa way.
var koa = require('koa'); var app = koa(); //Order of middlewares app.use(first); app.use(second); app.use(third); function *first(next) { console.log("I'll be logged first. "); //Now we yield to the next middleware yield next; //We'll come back here at the end after all other middlewares have ended console.log("I'll be logged last. "); }; function *second(next) { console.log("I'll be logged second. "); yield next; console.log("I'll be logged fifth. "); }; function *third(next) { console.log("I'll be logged third. "); yield next; console.log("I'll be logged fourth. "); }; app.listen(3000);
When we visit '/' after running this code, on our console we will get −
I'll be logged first. I'll be logged second. I'll be logged third. I'll be logged fourth. I'll be logged fifth. I'll be logged last.
The following diagram summarizes what is actually happening in the above example.
Now that we know how to create our own middleware, let us discuss some of the most commonly used community created middleware.
A list of third party middleware for express is available here. Following are some of the most commonly used middleware −
We'll discuss multiple middleware in the subsequent chapters.