@ukab/modular
v0.1.0
Published
Ukab Ecosystem modular framework
Downloads
1
Maintainers
Readme
Modular system for NodeJS
This package is used to create a modular NodeJS project. However the package itself does not provide any valuable funcationaly unless used with some platform. This package serves as a modular base, You can code any desired Platform around. Platform can be a Web Framework, CLI Application, Standalone Application etc. It's the Platform that possesses valuable functionality.
Ukab Modular Platforms
Why Modular?
Modular is based my opinion and It's okay if you do not share those opinions.
You may have lot of questions in your mind like:
- Why not NestJS?
- Why another modular framework?
- How it different from other?
- What advantages it has over NestJS?
I swear, I'm saying it politely, I don't have time to answer these questions. Give it a try and get answered yourself. Thanks! If you are going read all the shit.
Goals
- Keep it as simple as possible
- Maintain fairly minimal core
Read reference Docs
Components
The platform should or may (Depends on what platform wants to achieve) respect the ideology of each component. However the platform is free from any strict boundary so can declare and play with it's own rules and can utilize required components of the modular system in it's own way. Rules declared here only apply to Ukab Ecosystem's specific platforms.
Modules
Module is an isolated unit (Can also be considered as sub-application or application level service) that encapsulates a closely related set of business/domain features or logical components in an effective way.
You can declare a module with a class annotated with @Module() decorator. The @Module() decorator provides metadata that the platform can utilize to organize the application structure.
Each application has at least one root module. This root module should be considered the starting point of an application. Theoretically a very small application can only have a root module, But the most applications can utilize multiple modules. Each module encapsulates a closely related set of features or capabilities.
Module object is initiated during registration and Each module can only be registered once per application context. Modules can have controllers and providers, and can import other modules. By default providers can only be used within the host module, but can also be shared across modules by declaring them in exports and importing that module (which have the provider in exports) or can be declared as root providers that can be accessed across application context.
A provider that is not a part of the given module nor exported from one of the imported modules (as module encapsulates providers by default) and is not visible in root, cannot be consumed. Exported and Root providers are considered as public api/interfaces.
Modules futher divide into 4 categories:-
Feature Modules A feature module simply organizes relevant code for a specific feature or set of capabilities while respecting established boundaries. This helps to manage complexity and develop with SOLID principles, especially as the size of the application and/or team grows.
Shared Modules Every module that exposes public apis or provides some set of features, can be a shared module. Once created it can be reused by any module.
Root Modules It can be tedious to import the same module everywhere for the required set of capabilities. When you are in this kind of situation, where you have a module that is required by every other module, Mark that as the Root Module.
Dynamic Modules Consider the situation where you need a general purpose module that needs to behave differently in different situations. A Dynamic Module may rescue you from this kind of situation, assuming that module is configurable or needs some dynamic providers based on the current environment.
Module Factory
Platforms may consider making their framework compatible with the modular factory function that is the provider to create/initiate applications for the end-user.
Providers
There are fundamental units, many of the modular system classes may be treated as provider. The purpose of a provider may vary depending on the implementation, But the main idea of a provider is that it can be injected as dependency. Basically you can autowire provider or may inject it with custom identity. A Service Class may be a good candidate to be defined as a provider. Service may be responsible for data storage or retrieval, designed for the controller consumption.
Default Characteristics
Modular creates an ioc link of each provider. Currently, only linking of root providers can be prevented by overriding Abstract Application method rootProvider() that is called during the Provider Registration Phase.
Controllers
The purpose of the controller is to receive the request for the application and give appropriate reply to the request. Modular system does nothing with controllers. It's platform takes what it likes the controller to be, it can use them accordingly. So basically modular systems treat controllers as public apis for end-users.
Middlewares
In a modular system, Middleware is a functionality that can be called before or is a logic that should be executed before. Before may refer to request or something else depending on the utilizing platform. Only rule here is , Should be called before with ExecutionContext. Modular system itself does not consume middlewares. So it's a Platform choice to adhere to it or not.
Guards
Guards are given the responsibility to determine whether the call should proceed or not depending on certain conditions (like permissions, roles, ACLs, etc.) present at run-time. Calls can be requested by the controller's method. You can refer to it as authorizer. Modular itself does not consume guards and leaves it to Platform's admiration. The only prospective Modular give is to execute guards after middlewares.
Pipes
A pipe can be utilized to transform data into desired form or to evaluate. Pipe should terminate current execution in case evaluation fails. Platform can implement pipes if they admire it. Modular have nothing to do with them.
Filters
Filters can be used to sanitize inputs or filter errors/exceptions. Platform may utilize if they admire otherwise Modular have nothing to do with them.
Interceptors
Modular have nothing to do with interceptors. Platform can use them to separate cross-cutting concerns by allowing developers to add additional behavior to existing code without modifications. Instead of modifying code, behavior can be twisted or enhanced with a pointcut modifier, such as logging all errored requests.
Interceptors may be able to bind extra logic before or after execution, may transform returned result, may transform or swallow thrown exceptions, completely overriding a call/logic or partial behavior change, depending on specific scenarios like caching.
Execution Context
Platform may use ExecutionContext or may extend it to provide information about the current context that may be utilized by middlewares,guards,filters,interceptors etc.
Module Reference
Modular creates and registers ModuleRef for each module that can be used to obtain reference to any provider using the provider's identity.
Reflector API
Modular system's Reflector api is available in each module that can be utilized to read objects metadata. Platform can and is free to remove this api from module context.
Abstract Application
Platform may extend the AbstractApplication class to utilize generic functionality. Modular do not force Platforms to use Abstract Application, However platform should respect or implement IApplication interface as ModuleFactory depends on this contract to initiate module.
Usage
The Web Framework (modular-platform-http) package is the best sample code available on Modular implementation.
Highlights
Modular creates ioc link for each provider.