Create a perfect architecture in Laravel in 10 steps

The first question you need to answer before you start developing any Laravel application, is “How to make my project’s architecture more maintanable and scalable?” because any project is seen to evolve over time and to be maintained and most of the time by a different team than the one that developed it.

But what is the perfect architecture to use?

There isn’t one architecture or ONE perfect architecture and another isn’t, but we can make our project’s architecture almost perfect by following a few steps.
On this article I explain in 10 steps how to make the architecture of your project “PERFECT”:

  • Step 1: Create a folder structure
  • Step 2: Define your database schema
  • Step 3: Create Models
  • Step 4: Create DTOs
  • Step 5: Create Repository classes
  • Step 6: Create Service classes
  • Step 7: Create Controllers
  • Step 8: Wire up the layers of your application
  • Step 9: Define your application routes
  • Step 10: Test your application

Step 1: Create a folder structure

The first step in creating a perfect architecture in Laravel is to create a folder structure that will house the various components of your application. You can create folders named ModelsDTOsRepositoriesServices, and Controllers. This will help keep your code organized and make it easier to maintain.

The next folders are already created by default in any Laravel project: Models and Controllers

So, your project structure will look to something like the following:

├─ DTO/
├─ Http/
│ ├─ Controllers/
├─ Models/
├─ Services/
├─ Repositories/

As you can see all the folders we have created are located in the app/ root folder.

Step 2: Define your database schema

The next step is to define your database schema. This involves defining your database tables and their relationships. You can use Laravel’s built-in migration tool to create your database tables.

Of course, before you start defining your migrations you need to do your designing phase, … then you can use the Laravel migrations to make it easy to create your database schema.

To create a migration you can use the following artisan command to have more information:

php artisan make:migration -h

Step 3: Create Models

After defining your database schema, you can create your Models by extending Laravel’s Eloquent Model class. Your Models will represent the entities in your database schema.

At least, for each of your database table you need a model that defines this table as an entity into your Laravel project.

To create a model you can use the following artisan command to have more information:

php artisan make:model -h

Step 4: Create DTOs

Create DTOs (Data Transfer Objects) which are classes that contain only properties that you want to transfer between layers of your application, such as between the Controller and the Service layers. These DTOs help to decouple the layers of your application.

To have more information about using DTO in Laravel you can check my other Medium article here:

Step 5: Create Repository classes

Create Repository classes that will handle all database queries related to a specific entity. These classes will use the Model classes to interact with the database. The Repository classes will provide an interface for the Service classes to interact with the database.

But why using repositories instead of directly playing around with Model classes?

That’s simple! If you are using Model to communicate with your database you will have the same code (logic) everywhere on your application, and when you have make some changes on your code, you have to modify everywhere!
Otherwise, by using Repositories, all you have to do is to modify a specific function so the new logic will be implemented, and you’re good to go!

Step 6: Create Service classes

Create Service classes that will handle the business logic of your application. Services will use Repositories to interact with the database and perform actions on the Models. The Services will also use the DTOs to transfer data between layers.

This pattern is used to centralize your functionalities, and allow your application when needed to call the service to perform this functionality. The same for Repositories, all your logic is centralized in one place and by modifying your service makes it available on all your application.

Step 7: Create Controllers

Create Controllers that will handle HTTP requests and responses. Controllers will use the Service classes to execute business logic and return responses to the client.

To create a controller you can use the following artisan command to have more information:

php artisan make:controller -h

What you need to know, all your business logic must be located in your services and the controllers are here to call the services to do the job. You can see a controller like an “Orchestra Conductor”.

Step 8: Wire up the layers of your application

In Laravel, you can use Service Providers to bind your classes to the Laravel service container. Use Dependency Injection to inject the necessary dependencies into your classes. This will help to keep your code decoupled and easy to maintain.

When creating Repositories and Services, you should use interfaces to define your classes methods signatures, let’s make an example:


namespace App\Services;

use App\DTO\UserDTO;

interface IUserService

public function findAllUsers();

public function createUser(UserDTO $userDto);

public function updateUser(int $id, UserDTO $userDto);

public function deleteUser(int $id);


Then you need to define your class, so let’s continue:


namespace App\Services;

use App\DTO\UserDTO;
use App\Repositories\IUserRepository;

class UserService implements IUserService

private $userRepository;

public function __construct(IUserRepository $userRepository) {
$this->userRepository = $userRepository;

public function findAllUsers() {
return $this->userRepository->findAll();

public function createUser(UserDTO $userDto) {
return $this->userRepository->create([
'name' => $userDto->name,
'email' => $userDto->email,
// ... other fields

public function updateUser(int $id, UserDTO $userDto) {
$user = $this->userRepository->findById($id);
$user->name = $userDto->name;
$user->email = $userDto->email;
// ... other fields
return $this->userRepository->save($user);

public function deleteUser(int $id) {
$user = $this->userRepository->findById($id);


You can see that we are using here a Dependency Injection in our class constructor, and it’s the interface that is used in the injection.

To make this link between the interface and it’s implementing class, you need to add a bind call into your provider (you can use a specific provider to bind all your interfaces, or add it to your AppServiceProvider ), the following code should be placed into the register() function of your provider:

// ...
use App\Repositories\IUserRepository;
use App\Repositories\UserRepository;

// ...
$this->app->bind(IUserRepository:class, UserRepository::class);

And you can do the same for your services so you can use them into your controllers.

Step 9: Define your application routes

Define your application routes in Laravel’s web.php or api.php files. Map each route to a Controller method. This will help to define the endpoints of your application and how they interact with the Controllers.

For more details about Laravel routes, check the official docs here:

Step 10: Test your application

Test your application to ensure that everything is working as expected. You can use Laravel’s built-in testing framework to write tests for your ControllersServices, and Repositories. This will help to ensure that your application is robust and free from bugs.

For more details about Laravel testing, check the official docs here:

Happy coding!




Repository Pattern




Enjoy the read? Reward the writer.Beta

Your tip will go to EL OUFIR Hatim through a third-party platform of their choice, letting them know you appreciate their story.Give a tip

More from EL OUFIR Hatim


I’m a Full Stack developer who is passionate about making open-source more accessible and building community.

Jan 31

SOLID principles in Laravel

SOLID is a set of five design principles that promote software design that is robust, maintainable, and scalable. SOLID stands for: Single Responsibility Principle (SRP) Open/Closed Principle (OCP) Liskov Substitution Principle (LSP) Interface Segregation Principle (ISP) Dependency Inversion Principle (DIP) Each principle serves as a guideline to promote good design…


5 min read

SOLID principles in Laravel

Share your ideas with millions of readers.

Write on Medium

Feb 28

What is DTO and how to use it in a Laravel application?

DTO stands for Data Transfer Object, which is a design pattern used to transfer data between different layers of an application. In a DTO, data is encapsulated into an object, which can then be easily passed between different parts of the application. In a Laravel application, DTOs can be used…


2 min read

What is DTO and how to use it in a Laravel application?

Jan 13

Laravel – Generate translations automatically

As a Laravel developer I understand the struggle to make a multi-language application. You need to maintain your translation files, don’t forget about translations in your source code, … So I decided to let Google Translate do it for me, and automatically 😎 Install the package First thing to do, is to…


2 min read

Laravel – Generate translations automatically

Jan 31

Make your Laravel 9 faster!

Laravel is a popular PHP framework used for building web applications. With its easy-to-use syntax and powerful features, it has become the go-to choice for many developers. However, in production, Laravel applications can sometimes run slow, leading to a poor user experience. …


3 min read

Make your Laravel 9 faster!

Mar 30, 2020

Laravel & Angular authentication

As a full stack developer I know very well the struggle when we forgot about basic things when we are changing between projects with different languages. This article will explain, as a todo list, the steps to


Por journey

system analyst lawyer journalist ambientalist

Deixar um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logo do

Você está comentando utilizando sua conta Sair /  Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

Conectando a %s

%d blogueiros gostam disto: