App Structure 2015

The following is a reference. A written account of how, at this present moment in my dev lifecycle, I structure applications. This is a post I hope to be able to look back on in six or twelve months and go, what the hell was I thinking. So, without further ado.

App\Controllers\MovieController
App\Bindings\MovieModelRouteBinding
App\Exceptions\MovieModelNotFoundException
App\Models\MovieModelInterface
App\Models\Eloquent\EloquentMovieModel
App\Queries\MovieRepositoryQueryInterface
App\Queries\MovieRepositoryQuery
App\Queries\MovieRepositoryQueryBagTrait
App\Repositories\MovieRepositoryInterface
App\Repositories\EloquentCached\EloquentCachedMovieRepository
App\Repositories\Eloquent\EloquentMovieRepository
App\Transformers\MovieModelTransformer

That’s 13 classes for a single model and its’ controller. But it does come with a few advantages.

  • The controller isn’t the only place where a repository is used. It can also be used in commands, events etc. All validation occurs within the repository, so there’s no inconsistencies.
  • All requests to the repository (beyond CUD and single) require a corresponding Query. This has two advantages:
    • The repository knows the query has been parsed, sanitised and validated. It can ask for a param without having to repeat any validation.
    • As the query knows what can change, it generates the keys for caching in one place.
  • By using interfaces, implementations can be swapped out with no impact. During initial dev, MovieRepositoryInterface => EloquentMovieRepository, but later on it’s swapped out for a CachedRepository (in effect a decorator around Eloquent) without having to touch the Eloquent or Interface classes.
  • And the smaller classes, the route binding, transformer (using Fractal) etc, make testing each bit a cinch.

Who knows, this time next year I might have gone back to a “Model” file that is basically just a bunch of SQL queries. But for now, this process has done well for the last few projects.