Note: This post is part of Learn How to Use TypeScript With Node.js and Express.js series. Click here to see the first post of the series.
Table of Contents
What Are Application-Level Middleware and Why Do We Need Them?
Application-level middleware is a type of middleware that generally runs throughout the whole application. In the case of express.js, this kind of middleware are bound to the application by using app.use()
. This means a middleware will be executed for all endpoints set in the application, unless we specify a specific path.
// use application-level middleware for all API endpoints
app.use(applicationLevelMiddleware());
// use application-level middleware for all API endpoints with the path of http://localhost:${port}/api/*
app.use('/api/', applicationLevelMiddleware());
We can use application-level middleware in express by using app.METHOD()
or a request method (GET, POST, PUT, DELETE). The endpoint with a specific request METHOD at a given route will need to go through a middleware first.
// use application-level middleware for http://localhost:${port}/api/ GET API endpoint
app.get('/api/', applicationLevelMiddleware());
Create a Logging Application-Level Middleware
Logging, a simple but yet important feature of any application, is an excellent candidate for application-level middleware. Logging will allow you to know exactly what time and, depending on the application, who triggered an API endpoint.
To create our middleware, we are going to create a middlewares folder inside the src/api folder. Feel free to create in a different location based on your application. However, if you are following the Learn How to Use TypeScript With Node.js and Express.js series, src/api/middlewares will be the location used for the series. Then, create a file called logger.middleware.ts and before we add the middleware logic, we are going to install uuid
package.
npm i -s uuid
npm i -D @types/uuid
Let’s also install chalk. Chalk is a nifty package to add color to the logs.
npm i -s chalk
Once installed the packages, we can add the following logic to our logger.middleware.ts file.
import { Request, Response, NextFunction } from 'express';
import { v4 as uuidv4 } from 'uuid';
import { blue, blueBright , green, red } from 'chalk';
const getProcessingTimeInMS = (time: [number, number]): string => {
return `${(time[0] * 1000 + time[1] / 1e6).toFixed(2)}ms`
}
/**
* add logs for an API endpoint using the following pattern
* [id][timestamp] method:url START processing
* [id][timestamp] method:url response.statusCode END processing
*
* @param req Express.Request
* @param res Express.Response
* @param next Express.NextFunction
*/
function logger(req: Request, res: Response, next: NextFunction) {
// generate unique identifier
const id = uuidv4();
// get timestamp
const now = new Date();
const timestamp = [
now.getMonth() + 1,
'-',
now.getDate(),
'-',
now.getFullYear(),
' ',
now.getHours(),
':',
now.getMinutes(),
':',
now.getSeconds()
].join('');
// get api endpoint
const { method, url } = req;
// log start of the execution process
const start = process.hrtime();
const startText = green(`START:${getProcessingTimeInMS(start)}`)
const idText = blue(`[${id}]`);
const timeStampText = blueBright(`[${timestamp}]`);
console.log(`${idText}${timeStampText} ${method}:${url} ${startText}`);
// trigger once a response is sent to the client
res.once('finish', () => {
// log end of the execution process
const end = process.hrtime(start);
const endText = red(`END:${getProcessingTimeInMS(end)}`);
console.log(`${idText}${timeStampText} ${method}:${url} ${res.statusCode} ${endText}`);
});
// execute next middleware/event handler
next();
};
export default logger;
Now, we are going to open the index.ts file, import the logger middleware and use it by using app.use()
.
import logger from './api/middlewares/logger.middleware';
// add logger middleware
app.use(logger);
Time to Test The Logger Middleware
Go ahead and start triggering the GET
api/teams
endpoint. Checkout the terminal for logs.
What’s Next?
So far we have covered Third-Party and Application-Level middleware. It’s time to check out how to use a router-middleware in Express.js with TypeScript.