Nest js Tutorial Series — Part 4: Modules and Middlewares
Modules
The architecture of nest is module-based, just like Angular. It’s a class annotated with a @Module()
decorator. The @Module()
decorator provides metadata that nest parses to structure the application. Each application has at least one module, a root module conventionally named AppModule
. Modules are like containers for a cohesive block of code dedicated to a workflow, or closely related set of capabilities. They can contain components, service providers, and pipes whose scope is defined by the containing module. They can import functionality that is exported from other modules, and export selected functionality for use by other modules. Thus, for most applications, the resulting architecture contains multiple modules, each encapsulating a set of functionalities.
The @Module()
takes a single object of type ModuleMetaData which has four different properties explained below.
imports — the set of the ‘imported’ modules.controllers — the list of controllers. (e.g. HTTP controllers)providers — the list of providers that belong to this module. They can be injected between themselves.exports — the set of components, which should be available for modules, which imports this module.
Feature Modules (A.K.A Submodules)
A feature module simply organizes code relevant for a specific feature, keeping code organized and establishing clear boundaries. This helps us manage complexity and develop with SOLID principles, especially as the size of the application grows. All the feature modules are sub-modules of the root module.
Shared modules
Creating shared modules allows you to organize and streamline your code. You can put commonly used providers, pipes, and components into one module and then import just that module wherever you need it in other parts of your app. In Nest, modules are singletons by default, and thus you can share the same instance of any provider between multiple modules easily.
Module re-exporting
Modules can export their internal providers. In addition, they can re-export modules that they import.
Global Modules
When you want to provide a set of providers which should be available everywhere out-of-the-box (e.g., helpers, database connections, etc.), make the module global with the @Global()
decorator. The @Global()
decorator makes the module global-scoped. Global modules should be registered only once, generally by the root or core module.
Middlewares
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. Middleware is a function which is called before the route handler. The next middleware function is commonly denoted by a variable named next
.
According to express documentation, 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.
There are two ways to implement middlewares in nest:-
- Class-based middleware with
@Injectable()
- Function-based.
So let’s start with class-based middleware.
Class-based middleware
Custom middlewares are implemented in a class with @Injectable()
decorator. The class should implement the NestMiddleware
interface.
To use the custom middleware in ApplicationModule. The ApplicationModule has to implement NestModule interface and modify the configure function to set the LoggerMiddleware.
Functional Middleware
Functional middleware is just like express way of writing middlewares.
To use the function middleware in ApplicationModule.
If you enjoyed this tutorial, please click the 👏 button and share to help others find it! Feel free to leave a comment below.
Next part — Pipes