"If a worker wants to do his job well, he must first sharpen his tools." - Confucius, "The Analects of Confucius. Lu Linggong"
Front page > Programming > Simplifying Data Transfer in Laravel with DTOs

Simplifying Data Transfer in Laravel with DTOs

Published on 2024-11-07
Browse:190

Simplifying Data Transfer in Laravel with DTOs

Here's a step-by-step example on how to create Data Transfer Objects (DTOs) using Laravel Data:

1. Install Laravel Data Package

To begin, install the spatie/laravel-data package using Composer. This package helps in creating DTOs and managing data efficiently.

composer require spatie/laravel-data

2. Create a Data Transfer Object (DTO)

After installing the package, we can create a DTO class for handling data transfer. Suppose we have a User entity, and we want to create a DTO for transferring user data.

Run the following Artisan command to generate a new DTO class:

php artisan make:data UserData

This will create a UserData class inside the App/Data directory.

3. Define Properties and Types in DTO

Now, let's edit the UserData class to define the properties and data types you expect for your DTO.

namespace App\Data;

use Spatie\LaravelData\Data;

class UserData extends Data
{
    public function __construct(
        public string $name,
        public string $email,
        public string $address,
        public ?string $phone = null  // Optional phone field
    ) {}
}

Explanation:

  • The __construct method automatically assigns the incoming values to the DTO properties.
  • The ?string $phone = null indicates that the phone property is optional.

4. Use DTO in a Controller

Now that the UserData DTO is created, we can use it inside our controller to handle incoming data, transform it, and pass it between layers of the application.

namespace App\Http\Controllers;

use App\Data\UserData;
use App\Models\User;
use Illuminate\Http\Request;

class UserController extends Controller
{
    public function store(Request $request)
    {
        // Validate the incoming request data
        $validatedData = $request->validate([
            'name' => 'required|string',
            'email' => 'required|email',
            'address' => 'required|string',
            'phone' => 'nullable|string',
        ]);

        // Create a UserData DTO
        $userData = UserData::from($validatedData);

        // You can now access $userData->name, $userData->email, etc.
        User::create([
            'name' => $userData->name,
            'email' => $userData->email,
            'address' => $userData->address,
            'phone' => $userData->phone,
        ]);

        return response()->json(['message' => 'User created successfully']);
    }
}

Explanation:

  • The UserData::from() method automatically maps the validated request data into the DTO object.
  • The DTO object can now be used to transfer data between the controller and the model (or other layers of the application).

5. Transform Data Using DTO

You can use the DTO for transforming data when returning responses as well. Let's modify the show method in the UserController to return user data through the DTO.

public function show(User $user)
{
    // Convert the User model to UserData DTO
    $userData = new UserData(
        name: $user->name,
        email: $user->email,
        address: $user->address,
        phone: $user->phone
    );

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

Explanation:

  • Here, we manually create a UserData DTO by passing the User model’s properties into the DTO constructor.
  • This DTO can be returned directly as a JSON response, ensuring a structured data format.

6. DTO with Collections

If you are working with collections of data, like fetching a list of users, the DTO package provides a simple method to handle collections as well.

public function index()
{
    $users = User::all();

    // Convert the collection of User models to a collection of UserData DTOs
    $userCollection = UserData::collection($users);

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

Explanation:

  • The UserData::collection($users) method maps each User model to the UserData DTO, transforming the entire collection into a list of DTOs.

7. Customize Data Transformation

The spatie/laravel-data package allows customization of the transformation, for example, renaming attributes or adding computed fields.

class UserData extends Data
{
    public function __construct(
        public string $name,
        public string $email,
        public string $address,
        public ?string $phone = null
    ) {}

    // Add a custom method to compute a full contact string
    public function fullContact(): string
    {
        return "{$this->name} ({$this->email})";
    }
}

Now, you can use fullContact() to get a custom formatted string when working with this DTO.

8. Data Validation and DTOs

You can add validation rules directly in the DTO using Laravel Data’s Rules feature.

namespace App\Data;

use Spatie\LaravelData\Attributes\Validation\Email;
use Spatie\LaravelData\Attributes\Validation\Required;
use Spatie\LaravelData\Data;

class UserData extends Data
{
    public function __construct(
        #[Required] public string $name,
        #[Email] public string $email,
        public string $address,
        public ?string $phone = null
    ) {}
}

Explanation:

  • With validation attributes like #[Required] and #[Email], you can enforce validation directly on the DTO level, streamlining the process even further.

Conclusion

In this hands-on tutorial, we explored how to create and use Data Transfer Objects (DTOs) using Laravel Data. With the DTO pattern, you can cleanly manage and transform your data, ensuring separation of concerns between your application's layers, while making code easier to maintain. The spatie/laravel-data package simplifies DTO management, offering easy-to-use features for both developers and large-scale applications.

Release Statement This article is reproduced at: https://dev.to/mdarifulhaque/simplifying-data-transfer-in-laravel-with-dtos-1il7?1 If there is any infringement, please contact [email protected] to delete it
Latest tutorial More>

Disclaimer: All resources provided are partly from the Internet. If there is any infringement of your copyright or other rights and interests, please explain the detailed reasons and provide proof of copyright or rights and interests and then send it to the email: [email protected] We will handle it for you as soon as possible.

Copyright© 2022 湘ICP备2022001581号-3