Refactoring series: Structuring Laravel - Part 1
Every time I start a new Laravel project, I take a little time to decide on how I want to structure it. Since Laravel allows me to organize the folders however I want, I have come up with a couple different approaches to tackle this.
Everything lives in the App namespace
The first approach I have taken was simply to put all files into the
App namespace. I placed everything next to the
Console folders. If I needed a place for Jobs or Presenters, I simply created a new folder right in the
App namespace. While this is PERFECTLY FINE, it might get a little messy as the project grows.
Please note, I still use THIS kind of structure in most of my apps.
The project contained a lot of classes related to Users, therefore I moved them into
For me, it feels a bit weird for the
app folder to contain
Users folder, which represents domain objects (your models, jobs, etc), along with
Providers folder, which provides a “framework-necessary bootstrap” such as
# The folder structure using the first approach app ├── Console │ └── Kernel.php ├── Exceptions │ └── Handler.php ├── Http │ ├── Controllers │ ├── Middleware │ └── Kernel.php ├── Jobs │ └── RegisterUser.php ├── Presenters │ └── ProfilePresenter.php ├── Providers │ ├── AppServiceProvider.php │ ├── RouteServiceProvider.php └── Users └── User.php
Domain logic lives in a dedicated folder
To avoid having all classes under the same namespace, I decided to move the domain objects into a dedicated folder. They would all live in a namespace like this:
OK, this solves the problem, doesn’t it? The domain logic and the “framework-necessary bootstrap” are separated.
However, I did not like that my domain logic, the thing that matters the most, is nested inside
App\Acme. It makes the impression that code placed in the
App namespace, is somehow more important than the domain logic.
# The folder structure using the second approach app ├── Acme │ ├── Jobs │ │ └── RegisterUser.php │ ├── Presenters │ │ └── ProfilePresenter.php │ └── Users │ └── User.php ├── Console │ └── Kernel.php ├── Exceptions │ └── Handler.php ├── Http │ ├── Controllers │ ├── Middleware │ └── Kernel.php └── Providers ├── AppServiceProvider.php └── RouteServiceProvider.php
Let’s reverse this.
The final approach I came up with was to move the “framework-necessary bootstrap” into
App\Support namespace. Instead of “hiding” the domain code, I’ll hide the code I do not really want to have.
This enabled me to move every domain related class a level up. Now, the
User class is accessible at
App\Users\User instead of
# The folder structure using the third approach app ├── Http │ ├── Controllers │ └── Middleware ├── Jobs │ └── RegisterUser.php ├── Presenters │ └── ProfilePresenter.php ├── Support │ ├── Console │ │ └── Kernel.php │ ├── Exceptions │ │ └── Handler.php │ ├── Http │ │ └── Kernel.php │ └── Providers │ ├── AppServiceProvider.php │ └── RouteServiceProvider.php └── Users └── User.php
Easy right? Well, moving the
App\Exceptions\Handler classes is not as seamless as moving the domain code. Therefore, I’ll dedicate my next post to a tutorial on how to push the “necessary” code into
Feel free to reach out to me on twitter.