3 minutes
From Flat to Modular
Transforming of a flat application structure to a modular one in a Zend Expressive project
In an Expressive project I ran into the issue, where the application grew much larger than initially expected. How about that? The project got initialized with a flat code structure, which is the default selection of the Expressive Skeleton. Flat basically means the application is organized in a single module in contrast to endless modules in the modular structure. It also means not only having separate modules but also separate namespaces. This makes handling class names much easier.
Looking back on it now I tend to always choose a modular structure. The only use case for a flat structure would be a micro application with very little backend code. Even then it is questionable as to why not using a modular structure, since the difference between the two are not that big and converting the structure later on is much more effort. But I am getting ahead of myself.
So the single module horded a ton of classes with their factories. This got quite heavy and sometimes confusing. To clear up all the confusion I decided to convert the code structure from flat to modular.
Flat vs. modular: the comparison
I could not find any documentation or user contributions on how to convert the structure. To find out what the differences are, I decided to create two new projects: one with a flat and one with a modular structure and then compare the two.
I create a new project with flat code structure. All default selections were chosen.
$ composer create-project zendframework/zend-expressive-skeleton expressive-flat
For modular structure first question What type of installation would you like? was answered with 3 - Modular. For all other options the default selections where chosen.
$ composer create-project zendframework/zend-expressive-skeleton expressive-modular
The structural differences of the two projects are (1) the location of the source file within the App
module, (2) a template folder and (3) the autoloading configuration.
Flat | Modular | |
---|---|---|
Source App Module | src/App |
src/App/src |
Template Ordner | n/a | src/App/templates |
Autoload configuration | "App\\": "src/App/" |
"App\\": "src/App/src/" |
Making the transition
Consequently, I needed to make the following changes to convert the project structure:
- Move contents of
src/App
tosrc/App/src
- Optional: Move the templates from within the
App
folder tosrc /App/templates
and adjust the configured templates path (in my case inconfig/autoload/application.global.php
) - Update the autoload configuration in
composer.json
to"App\\": "src/App/src/"
- Execute
composer dump-autoload
to update the autoloading classes
That’s it, the transition is made.
But my initial issue was not solved. I went ahead and re-organized the App
module, moving various folders into their own module. For each folder I repeated the following steps.
- Create a new module
$ composer expressive module:create {ModuleName}
- Moved classes from
src/App/src/{ModuleName}/
tosrc/{ModuleName}/src/
- Updated namespace of classes and imports from
App\{ModuleName}
to{ModuleName}
- Moved dependencies definitions from
backend/App/src/ConfigProvider.php
tobackend/{ModuleName}/src/ConfigProvider.php
Tadaa! Now the setup is much cleaner and simpler. Mission accomplished.
Gude Laune!