Amina
Amina's Blog

lorem ipsum

Aug 12, 2024 5 minute read

Data Transfer Objects (DTO) in Laravel

Table of Contents

  1. What is DTO?
  2. DTOs vs. Other Objects
  3. Creating a DTO in Laravel
  4. Useful Links

In modern PHP development, one of the key principles for building maintainable and scalable applications is the separation of concerns. This is where Data Transfer Objects (DTOs) come into play. DTOs are a simple yet powerful concept that can help you achieve cleaner, more organized code.

What is DTO?

A Data Transfer Object, or DTO, is a simple object designed to carry data between different parts of an application. Unlike entities or models, DTOs don’t contain any business logic—they’re just containers for data.

The main purpose of a DTO is to group related data into a single object, making it easier to pass data around your application. DTOs are especially useful in layered architectures, where data needs to be transferred between different layers, such as between a controller and a service.

Why use DTOs

Using DTOs in your PHP application comes with several benefits:

  • Separation of Concerns: DTOs help keep your business logic and data representation separate. This makes your application easier to understand and maintain.

  • Data Validation: You can use DTOs to ensure that only valid data is passed between layers. By validating data at the DTO level, you can catch errors early in the application flow.

  • Clarity and Readability: DTOs provide a clear structure for your data. Instead of passing multiple parameters around, you can group them into a single, well-defined object.

  • Consistency: DTOs ensure that data structures are consistent throughout your application, which is especially useful when dealing with APIs.

DTOs vs. Other Objects

Before diving into how to implement DTOs in PHP, it’s important to understand how they differ from other common objects:

  • DTO vs. Entity: Entities are objects that represent data in your database. They often contain business logic and are tied to a specific table or document. DTOs, on the other hand, are not tied to any database and should not contain business logic—they’re just used to move data around.

  • DTO vs. Value Object (VO): Value Objects are objects that represent a value and are typically immutable. They can include logic to enforce rules about the data they contain. DTOs, however, are mutable and are focused solely on data transfer, without any logic.

Creating a DTO in Laravel

In a Laravel application, DTOs can be a powerful tool for structuring data, particularly when interacting with services, APIs, or performing data validation.

Defining a DTO in Laravel

Suppose you have a scenario where you need to transfer user data between different layers of your application, such as from a controller to a service. In Laravel, you might define a DTO like this:

  1. Create a DTO class: In Laravel, you might store your DTOs within the App\DTOs directory. You can create this directory and then add your DTO class there:

    php artisan make:directory DataTransferObjects
    
  2. Define the DTO: Create a UserDTO.php file inside the App\DataTransferObjects directory with the following content:

    namespace App\DTO;
    
    class UserDTO
    {
        public string $name;
        public string $email;
        public string $password;
    
        public function __construct(string $name, string $email, string $password)
        {
            $this->name = $name;
            $this->email = $email;
            $this->password = $password;
        }
    }
    

In this example, the UserDTO class contains three properties: $name, $email, and $password.

Using the DTO in a Laravel Controller

Now, the DTO can be used within a Laravel controller, for example, to create a new user:

namespace App\Http\Controllers;

use App\DTO\UserDTO;
use App\Services\UserService;
use Illuminate\Http\Request;

class UserController extends Controller
{
    private UserService $userService;

    public function __construct(UserService $userService)
    {
        $this->userService = $userService;
    }

    public function createUser(Request $request)
    {
        $userDTO = new UserDTO(
            $request->input('name'),
            $request->input('email'),
            $request->input('password')
        );

        $user = $this->userService->createUser($userDTO);

        return response()->json($user);
    }
}

In the above example, the createUser method in the UserController receives a Request object from the client. It then creates a new UserDTO object using the input data from the request, and passes this DTO to the createUser method of the UserService. The UserService can then use the DTO to create a new user in the database, without having to know anything about the request or the controller.

Using the DTO in a Laravel Model

Now you can link your DTO to your Model and then save it into your database:

namespace App\Services;

use App\DTO\UserDTO;
use App\Models\User;

class UserService
{
    public function createUser(UserDTO $userDTO): User
    {
        $user = new User();
        $user->name = $userDTO->name;
        $user->email = $userDTO->email;
        $user->password = $userDTO->password;
        $user->save();

        return $user;
    }
}

In the createUser method, a new User model is created, and its properties are set using the values from the $UserDTO. The model is then saved to the database using the save() method.


Amina