The example you posted is demonstrating how to use middleware in Koa. Middleware is functionality that wraps your application and can modify the request as it comes in (before it reaches your application code) or the response as it’s returned.
As I understand it, the middleware functions are executed in the order they are attached. In the example, when a request comes in, the response time function is called first. This creates a new Date object in order to capture the time at the start of the request.
It then calls await next(); which pauses the execution of the current function (using the await keyword) and passes control to the next middleware (the logger). The logger then performs some logic (in this case, creating its own Date object) and then pauses and passes control to the next function.
As there is no additional middleware to pass through, the request ends up at the function which generates the response (returning the string 'Hello World'). This function doesn’t call next(), so when it terminates the control passes back to the previous function in the chain (the logger) which resumes where it left off.
The logger middleware calculates the ms taken for the request, and logs out the method, URL and ms before returning control to the response time function. That function then recalculates the response time in ms and appends it to the outgoing request as a header and returns.
As there is no further middleware in the stack, the response is now returned to the user.
The benefit of the async/await syntax here is that it makes asynchronous code easier to follow. Rather than having a bunch of nested callback functions (or chained Promises) you can read the code as if it was synchronous.
I hope that helps, but let me know if anything was unclear.
I understand how they work. I used similar code when I created my little API but the await next() I do not get. In the first example, we used next not to hold up other middleware but in this case, we are just rendering there is no other middleware. I removed the await next() and the code still worked!
Anyway, I might need to learn more about middleware.
One last thing, this might be off topic. I have this code which I actually understand
See that the first function declares next as the second argument and calls it to pass control to the second function, while the second function doesn’t bother declaring next as it’s not used. So in your example, as you’re only declaring a single function per route, you don’t need to worry about calling next().
You can add a second middleware function beneath the first to throw an error: