As you know, Magento 2 is notable for its scalability or extensibility also.
Extensibility means how easy it is to expand a product’s feature sets. An extensible product has been designed from its earliest stages for customization and enhancement.
Modularity is one of the Magento 2 extensibility concepts. So modular design of software components (in particular, modules, themes, and language packages) is a core architectural principle of Magento. Self-contained modules of discrete code are organized by feature, thereby reducing each module’s external dependencies.
So in this topic, you will learn about Magento extensibility & modularity.
1. Module Overview
What is a Magento module?
A module is a directory, an independent component, or a set of parts containing blocks, controllers, helpers, and models which provides business logic and features. Conforming to Magento’s commitment to optimal modularity, a module encapsulates one functionality and has minimal dependencies on other modules.
Purpose of a module
A module implements new functionality or extends the functionality of other modules to offer particular product features. Each module is designed to execute separately, so adding or excluding a module does not affect the functionality of the others.
Module components
A module is a folder that contains the PHP and XML files that are related to a specific business feature. A Magento module is composed of these software components: themes, libraries, and language packages.
Module locations
There are two areas where a module can be located in a Magento 2 application.
The first location is an app/code directory. We use this directory to add custom and 3rd-party Magento 2 modules. It is usually used by development agencies, internal or in-house developers to simplify the development process.
The second location is a vendor directory. It is used when developers install composer package management.
Module location conventions
In case you prefer customizing or extending Magento to editing core files directly, or placing new Controllers, Models, Helpers, Blocks, etc. next to Magento code, you’ll create your own Modules in the /app/code/<Vendor>/<Module>
Vendor (or a Namespace)specifies your company or organization. You use it to create modules in order to make them different from another user’s code.
2. Module and areas
Overview
An area is considered as a logical part to organize code for optimized request processing. We use it to streamline web service calls by loading only the dependent code for the specified area. This area is defined by Magento and contains different code on how to process URLs and requests.
Magento area types
Magento is arranged into 3 main areas:
- adminhtml: the entry point for Magento admin area is index.php or pub/index.php. This area contains the code for store management
- front end: the entry point for the storefront area is index.php or pub/index.php. This area includes template and layout files that define the appearance of the storefront.
- base: This area is used as a fallback for files absent in adminhtml and frontend areas.
- Cron: The \Magento\Framework\App\Cron class always loads the ‘crontab’ area, in pub/cron.php.
You are able to send requests to Magento using the SOAP and REST APIs. These two areas are:
- webapi_rest: the entry point for web api rest area is index.php or pub/index.php. It has a front controller that understands how to do URL lookups for REST-based URLs.
- webapi_soap: entry point for web api soap area is index.php or pub/index.php.
How areas work with modules
Modules define which resources are visible and available in a field and its behavior. The same module can influence several areas. For instance, the A module is set partly in the adminhtml and frontend area.
Ensure that your module has separate behavior and view components for each area if it works in several different regions. Each area declares itself within a module. All specific resources for a domain are located within the same module as well.
You can disable or enable an area within a module. If this module is activated, it injects an area’s routers into the general application’s routing process. If it is disabled, Magento will not load an area’s routers, and as a result, an area’s resources and specific functions are not available.
Module/area interaction guidelines
- It is not recommended to make modules depend on other modules’ areas.
- If you disable an area, it does not mean disabling the modules related to it.
- Areas are registered in the Dependency Injection framework di.xml file.
Notes about request processing in Magento
A URL request is handled by stripping off the base URL. The first path segment of the remaining URL identifies the request area.
After the area name, the URI segment specifies the front name. The handle is extracted from the URL when an HTTP request arrives and interprets it as follows:
[front_name]/[controller folder]/[controller class]
- The front_name is a value defined in the module. Using catalog/category/view like an example:
- catalog is the front_name in the module area’s routes.xml file
- category is the controller folder
- view is the controller class
3. Module relationships
Overview
To determine how a module reacts to changes, we must understand how it relates to another.
A module can have bellow types of relationships:
- uses: module A uses module B if it calls the behavior of module B.
- reacts to: module A responds to module B if an event in module B triggers its response without module B knowing about module A.
- customizes: module A customizes module B if it adjusts the behavior of module B.
- implements: module A implements module B if it implements some, not necessarily all, behavior that is defined in module B.
- replaces: module A replaces module B if it provides its API version exposed and implemented by module B.
4. Module dependencies
Overview
A software dependency points out a software component’s dependency on another for proper operation. A fundamental principle of Magento architecture is the minimization of software dependencies.
Contrary to being closely interrelated with other modules, modules are optimally designed to be loosely coupled. So they require little or no knowledge of other modules to function their tasks.
Each module is responsible for a unique feature. Basic, this means:
- Some modules are responsible for one feature.
- One module is not responsible for some functions.
- Module dependencies on others must be declared explicitly. You also need to declare any reliance upon other components
- Removing or disabling a module does not mean disabling other modules.
Dependencies types
Hard dependencies
Specify that a module cannot function without the other modules on which it depends. Example:
- These modules includes code which uses logic from another module (for instance, class constants, static methods, public class properties, interfaces, and traits)
- Contain strings that include class names, method names, class constants, class properties, interfaces, and traits from another module.
- Deserializes an object declared in another module.
- Uses or adjusts the database tables used by another module.
The require section of composer.json file contains hard dependency definitions for the module.
Soft dependencies
A soft dependency module which depends on another module can perform accurately without the others, even when it is dependent on the other module. For example:
- Directly check another module’s availability.
- Extend another module’s configuration.
- Extend another module’s layout.
The suggest section of composer.json file contains soft dependency definitions for the module. For example:
...
"suggest": {
"magento/module-graph-ql": "*",
"magento/module-graph-ql-cache": "*",
"magento/module-store-graph-ql": "*"
}
...
The <sequence> node of module.xml file in app/code/<Vendor>/<Module>/etc/ also contains soft dependency definitions for the module. For example:
<module name="Magento_Cms">
<sequence>
<module name="Magento_Store"/>
<module name="Magento_Theme"/>
<module name="Magento_Variable"/>
</sequence>
</module>
Note: If a module uses code from another module, it should declare the dependency explicitly.
Module install order
Magento installs modules following this order:
- The module acts as a dependency for another module
- The module is dependent on it
Appropriate dependencies
Although Magento architecture is loosely coupled software components, modules can include dependencies upon these software components:
Inappropriate dependencies
You should not create these dependencies:
- Circular (both direct and indirect)
- Undeclared
- Incorrect
Dependencies between modules in different presentation layers
You are able to create dependencies between the modules that belong to various layers.
Dependencies in the Framework layer
A module belonging to the Magento Framework can be used in the application layer by an explicit dependency.
Note: In this case, using interfaces is preferable to using classes. You can build dependencies between classes in the Magento Framework even if they belong to different modules.
Dependencies in the application layer
A module which belongs to the application layer cannot be used in the Magento Framework.
You can build dependencies between classes in the application layer, but these classes need to belong to the same module. Dependencies between the modules of the application layer should be built only by the service contract or the service provider interface (SPI).
Managing module dependencies
At a high level, there are three main steps for managing module dependencies:
- Name and declare the module in the module.xml file.
- Declare any dependencies that the module has (whether on other modules or on a different component) in the module’s composer.json file.
- (Optional) Define the desired load order of config files and .css files in the module.xml file.
For example: Module A declares a dependency upon Module B. So, in module.xml file of module A, Module B is listed in the <sequence> tag. Thus, module B’s files are loaded before module A’s. Plus, you must declare a dependency upon Module B in the composer.json file of module A. Moreover, in the deployment configuration, Modules A and B must both be defined as enabled
etc/module.xml
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="ModuleA" setup_version="1.0.0">
<sequence>
<module name="ModuleB" />
</sequence>
</module>
</config>
After installing the module, you can open app/etc/config.php to see the order of modules, in this case, the Module_B was loaded before Module_A:
return [
'modules' => [
'ModuleB' => 1,
'ModuleA' => 1,
]
];
5. Conclusion
I hope that this article brings you useful information about extensibility and modularity in Magento 2. If you have any questions, feel free to leave us your comments. Don’t forget to keep updated with us for more Magento 2 tutorials.