Modularity
Modules provide a structured way to organise code, breaking it into logical units representing specific layers or functionalities. This modular approach improves maintenance and scalability by reducing dependencies and encapsulating implementation details. Loose coupling between modules allows for easier modification of individual components without affecting others. Explicitly declaring dependencies facilitates better dependency management and reduces conflicts. Modularization promotes code reuse, facilitating the creation of reusable components and easier incorporation into different projects. Additionally, breaking a project into modules enables more effective testing, optimisation, and performance improvements for individual components.
Taking a Leapwise approach, one typically discovers applications structured with at least four modules:
API: The API module defines the rules of interaction for the application. It contains service interfaces an application offers, request-response pairs, and data models used for data exchange. The API module abstracts the underlying business logic, ensuring that external integrations depend only on the API module without exposing the intricate details of internal processing. This approach reduces the memory footprint of an application for integrators. The API module should not contain any business logic, and it is crucial to be properly documented as it represents a contract for integration with application.
CORE: The Core module encapsulates the essential business logic of an application. It implements services defined in the API module, manages data storage and retrieval operations, validates incoming requests, and handles application configuration. By abstracting implementation details, the Core module ensures smooth execution of critical operations. Thorough test coverage, including JUnit and integration tests, is essential because it ensures the reliability of the Core module's business logic, safeguarding against potential errors and failures in critical operations. Decoupling Core from other modules boosts modularity and maintainability, enhancing system robustness and adaptability.
PACKAGING: The Packaging module manages application packaging and distribution, crucial for efficient deployment. We utilize it for Debian, RPM, and Kubernetes environments. The Debian Maven Plugin generates Debian packages (.deb) for deployment on Debian-based Linux systems like Debian, Ubuntu, and related distributions. The RPM Maven Plugin creates RPM packages (.rpm) suitable for Red Hat-based Linux distributions such as RHEL, CentOS, and Fedora. For Kubernetes, the module incorporates configuration files defining the packaging, deployment, and management of applications within Kubernetes clusters.
WEB/SERVER: The web module typically contains the main application class, representing the entry point of an application. It also enables the exposure of service interfaces defined in the API module through various different communication protocols, ensuring compatibility with diverse client applications and systems, such as REST, SOAP, JBR, and others. The Web module minimizes coupling between API definitions and communication protocols, ensuring easy adaptation to different protocols without altering the core business logic.
In addition to the previously mentioned modules, a project's specific requirements may necessitate additional modules. For instance, shared code across multiple modules is commonly centralized within a common module. Furthermore, integration-specific classes or auto-generated code from designated contracts are typically organized within either an integration or generated module.
In scenarios where multiple integration points exist, each might have its own dedicated module, or alternatively, these could be organised as submodules within an integration module for better organisation and management.