Middleware
Intro
Middleware is computer software that provides services to software applications beyond those available from the operating system.
Middleware makes it easier for software developers to implement communication and input/output, so they can focus on the specific purpose of their application. It gained popularity in the 1980s as a solution to the problem of how to link newer applications to older legacy systems, although the term had been in use since 1968.
Middleware can be described as a "software glue"
Benefits
The middleware pattern provides extensibility to a "closed" system. It allows injecting behavior without inheritance or source modification. Middleware is one pattern that helps facilitate the implementation of the Open closed principle (The "S" in the SOLID principles).
- Extends software without modification
- Provides a chain of responsibility
Fundamentals
At the most basic level, Middleware provides a hook into the chain of responsibility. This hook
lets you manipulate the payload and/or pass the payload onto the next operation in the chain.
app.use(function (req, res, next) {
console.log('Time:', Date.now());
next();
});
A typical pattern of registering middleware is done through a use
method.
var express = require('express');
var app = express();
var cookieParser = require('cookie-parser');
// Load the cookie-parsing middleware.
app.use(cookieParser());
Application
Middleware is not a new or exclusive concept. It has been around for a very long time in different forms. The term "middleware" is most notably used within the Node Express.js framework.
Possible Uses
- Logging requests
- Authenticating/authorizing requests
- Parsing the body of requests
- End a request – response lifecycle
- Call the next middleware function in the stack.
Logging
app.use(function (req, res, next) {
console.log('Time:', Date.now());
next();
});
Error-handling
app.use(function (err, req, res, next) {
console.error(err.stack);
res.status(500).send('Something broke!');
});
Express.js
Express is a routing and middleware web framework that has minimal functionality of its own: An Express application is essentially a series of middleware function calls.
Middleware
functions are functions that have access to the request object (req), the response object (res), and the next middleware function in the application’s request-response cycle. The next middleware function is commonly denoted by a variable named next.
Middleware functions can perform the following tasks:
- Execute any code.
- Make changes to the request and the response objects.
- End the request-response cycle.
- Call the next middleware function in the stack.
- If the current middleware function does not end the request-response cycle, it must call next() to pass control to the next middleware function. Otherwise, the request will be left hanging.
An Express application can use the following types of middleware:
- Application-level middleware
- Router-level middleware
- Error-handling middleware
- Built-in middleware
- Third-party middleware
- You can load application-level and router-level middleware with an optional mount path. You can also load a series of middleware functions together, which creates a sub-stack of the middleware system at a mount point.
Middleware functions are functions that have access to the request object (req), the response object (res), and the next middleware function in the application’s request-response cycle. The next middleware function is commonly denoted by a variable named next.
Express Resources
Angular
Interceptors in Angular, as the name suggests, is a simple way provided by the framework to intercept and modify the application’s http requests globally
before they are sent to the server. That really comes in handy, allowing us to configure authentication tokens, add logs of the requests, add custom headers that out application may need and much more.
"Interceptors can perform a variety of implicit tasks, from authentication to logging, in a routine, standard way, for every HTTP request/response. Without interception, developers would have to implement these tasks explicitly for each HttpClient method call."
Logging Interceptor
@Injectable()
export class RequestLogInterceptor implements HttpInterceptor {
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
console.log(request.url);
return next.handle(request);
}
}
Authentication Interceptor
@Injectable()
export class AuthenticationInterceptor implements HttpInterceptor {
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const storageUser = localStorage.getItem('LoggedUser');
const loggedUser = jsonInfo ? JSON.parse(jsonInfo) : null;
if (loggedUser) {
request = request.clone({
headers: req.headers.set('Authorization', loggedUser.authToken)
});
}
return next.handle(request);
}
}
HTTP Interceptor Resources
- https://medium.com/angular-in-depth/top-10-ways-to-use-interceptors-in-angular-db450f8a62d6
- https://blog.angulartraining.com/http-interceptors-in-angular-61dcf80b6bdd
- https://itnext.io/understanding-angular-interceptors-405b84d7ad69