Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement a Modular Architecture with symfony4

I would like to follow the recommendations of this article from Sander Mak, which advocates using a traditional Monolithic Architecture making use of modules instead of Microservices which are not a good choice in many cases : https://www.oreilly.com/ideas/modules-vs-microservices

I made lot of researches on Monolithic versus Microservices and came to the same conclusion that Monolithic is still the best bet in many cases and the same goals can be achieved in a much simpler way. Microservices should be used in really extreme and specific cases.

Of course the implementation of a good Modular Architecture is different in every language & frameworks. The author is speaking about Java 9 and how it has redefined completely the way of implementing such a Modular Architecture.

But what about Symfony 4 ? Prior to version 4 it seems that the right approach was to use Bundles. But since the version 4, the official documentation is clearly recommending to not do that anymore : https://symfony.com/doc/current/bundles.html

In Symfony versions prior to 4.0, it was recommended to organize your own application code using bundles. This is no longer recommended and bundles should only be used to share code and features between multiple applications.

But I could not see in the documentation what is the right way to do it now! If Bundles cannot be used, what would be the best practices then to implement a Modular Architecture as defined in the article of Sander Mak ?

like image 811
Erwan Rouzel Avatar asked Apr 18 '18 14:04

Erwan Rouzel


1 Answers

I am my self from Java environment, but have choose to write my current applications in SF4/PHP-7.x environment. Many reasons that are very long to enumerate here have made me choose SF4, after Laravel 5.x.

Don't be fouled by the Symfony 4 and 5 moves ... I admit I don't always understand all their evolution plan and marketing strategy, and I was frustrated at the start with the new bundle less application orientation announce. But instinctively, and maybe because I didn't have other choices, I strive to try SF4 with the convinced plan to reinforce my application modular strategy in the SF4 environment.

Thanks to the Sander Mak article on Modules vs Micro-services, in that it confirm my needs of for a modularity support framework, more than micro-services modular functionalities. The real stake here is to correctly evaluate what type and scale of organizational concepts you want to implement as modules. Modularized micro-services can surely be used to implement complex hardwares, business activities and detailed organization infrastructures. But at a heavy cost, and with many resources to deal with the dependencies and inter-connexions.

With SF4, although they usually spoke about micro-kernel, or build your own micro-service framework, I see their offer as a good monolithic platform, to build modular business applications. I admit the PHP OOP limits compared to java environment, make some implementations harder than desired, but at the end, for regular business applications requirements, the SF4 framework and components offer a good application basement.

Before diving in the best way to use SF4 for modular application dev, I will share my understanding of SF4 leaders vision / road map, for the next 2 years :

  • SF4 applications is a composition of 2 types of interconnected application modules : Api-component and Bundle
  • Api-Component : (google say) is defined as a modular, deployable, and replaceable part of a software system that encapsulates its behavior and data and exposes these through a set of interfaces. The most important fact here is that, API-component must implement a required (well bounded) business features, exposed through API.
  • Bundle : is also a component as defined for the api-component, but at a higher level of granularity. That means, Bundle usually use api-component (not inverse) and are mainly oriented to User/Client visual interface. Think of bundle as the implementation of mini-application, functional application, department level application features of an organization. e.g.: AccountingBundle, InventoryBundle, ProcurementBundle ... The granularity is left at the taste of each design team.
  • Starting with the SF4 bundle less environment, Symfony leaders decided to drop the AppBundle, because by experience, they know the overhead of creating a bundle versus a component module. So, the 'App' default component application is now the base environment to offer many solutions in one to application architect:

    1. 'App' component have all the capabilities of a bundle, with less coding, but it's considered as the central SF4 main module.
    2. 'App' main module can share App config, Templates, Resources with all added modules component and bundles
    3. Platform evolution consider that the provided Framework don't need to know to much about added modules, and the default 'App' will be where to put the glue for the framework extension.
    4. Implementing features in the 'App' main module, or in a api-component module, or in a bundle is now a code organization decision in their point of view.
    5. IMHO, the decision to create component or bundle is all defined by the application modularity requirements. So, decision to create a bundle or a component module is not mostly driven by the need to share the code in public space/market, but by the necessity to design a clean modularized, maintainable, reusable code.
    6. So, Every decision to split the code in modules must be challenged by business and technical requirements. When you decide which modules to create, it's easy to implement in SF4.
  • My recommendations for internal modules priority :

    1. First decide which modules you want to create and their configuration/parameters requirements.
    2. Centralize most configurations/parameters in the 'App' main module, using the benefits of .env environment utilities.
    3. Modules resources/translations can be created in 2 steps : First in main 'App' module for quick and easy validation. Then, move them in the specific bundle at a second step ...
    4. Transversal features such as Security, Configuration, and Core/Common services which are used by all other modules must be implemented at first in 'App' main module. With more experience, some features can be reorganized in featured components for more modularity and clarity.
    5. Place bundles and api-component under /src directory, with central composer PSR-4 autoload capacity, and exclude them from 'App' services.yaml
    6. Note that in this recommendation, we don't reinforce too much the autonomy of the modules against the 'App' main module. We choose to let them been slightly dependent of the central module config functions at the start. This is a gain in coding time and validation. Modules encapsulation can be reinforce progressively as developer gain more experiences in SF4 coding rules. By the way, the first objective is the Application delivery in time.

When time comes, and you want to share a particular module with the community, check to send back to the module, the minimal config/parameters required in external environment.

like image 81
kasor Avatar answered Sep 28 '22 07:09

kasor