Search code examples
phpsymfonystructurebusiness-logicsymfony4

Monolith structure in bundle-less Symfony 4


I started using and testing Symfony 4 for main project migration. I was used to getting told by Symfony on how files should be structured, but now when there are no more bundles, I wonder, how to structure huge monolith application.

Scale now: ~300 routes, ~70 controllers, ~90 entities, ~20 bundles

How services.yaml should look like? - should I stay on App namespace or maybe I could simulate bundles? Where to put service configuration for each component?

How services and controllers should be separated in directories? - Should I go for src/Service/{Something}/{Something}Manager.php or stay on src/{Something}/Service/{Something}Manager.php and just don't use Bundle keyword? Why?

Where would you put UserAuthenticationProvider and/or WebSocketServer?


Solution

  • I've made a new set of REST APIs for a legacy monolith application and faced the same questions.

    I will answer this question first: How services and controllers should be separated in directories?

    I went down the src/Service/{Something}/{Something}Manager.php path as I thought that that was the way. As the project has grown, I regret that and will be moving to src/{Something}/Service/{Something}Manager.php

    Why?

    1. I find the separation in namespacing much easier to read and much harder to accidentally use the wrong class.
    2. I now have files split out across the application and it's much harder to abstract it into a library that can be re-used by other applications.
    3. I can't refactor functionality as easily - everything is spread out an intertwined. If I were converting a monolith, I would prefer to have code to refactor that was bound by some function so I could work on that, before moving to the next.

    There are other reasons but feel the need to separate this back out before the application gets any larger.

    How services.yaml should look like? Well, the autowiring is amazing. I would keep your service yamls in the various functional splits (as above) and start refactoring them out. With the default autowiring config, you'll find that very little needs explicit definitions.

    Where would you put UserAuthenticationProvider and/or WebSocketServer?

    For the provider, probably something like, src/Security/Authentication/Provider/UserAuthenticationProvider.php.

    For the WS server, I'm not really sure - it depends where it sits in the app and how it's used.