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

Create project with modular code structure

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:

  1. Move contents of src/App to src/App/src
  2. Optional: Move the templates from within the App folder to src /App/templates and adjust the configured templates path (in my case in config/autoload/application.global.php)
  3. Update the autoload configuration in composer.json to "App\\": "src/App/src/"
  4. 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.

  1. Create a new module $ composer expressive module:create {ModuleName}
  2. Moved classes from src/App/src/{ModuleName}/ to src/{ModuleName}/src/
  3. Updated namespace of classes and imports from App\{ModuleName} to {ModuleName}
  4. Moved dependencies definitions from backend/App/src/ConfigProvider.php to backend/{ModuleName}/src/ConfigProvider.php

Tadaa! Now the setup is much cleaner and simpler. Mission accomplished.

Gude Laune!