Domain-Driven Design - Laravel

Domain-Driven Design - Laravel

Domain-Driven Design is a software development approach that tries to bring the business language and the code as close together as possible.

Introduction

In 2023 the term Domain-Driven Design gained more popularity in the developer's community. If you are from the Laravel development side you may hear this term more often in recent times. so, today we are going to discuss everything about Domain-Driven Design.

Domain-Driven Design

DDD (Domain-Driven Design) is a software development approach that tries to bring the business language and the code as close together as possible. This is the most critical attribute of this approach. But for some reason, DDD is one of the most misunderstood and overcomplicated topics in the developer community.

Why do we need DDD?

In software development, the hardest part is maintaining & building a new feature on existing software.DDD teaches us to structure our code in very expressive and logical. In the most simple Laravel application, you have models and controllers. What do you think when you see a project with 50 models and 50 controllers?

That seems reasonable but you have to dig deeper if you want to have a good understanding. Now, what about 300 models and 500 controllers? your project size may be grown up easily. Now it's a pain for a development team to maintain it in a native MVC or any other MV* architecture. That's where the approach comes into play as developers we prefer technical terms over business concepts.

Example :

Just see the code snippet below that I have written in one of my side projects a couple of months before (it's not Laravel).


    public function get_view_container_new_user(Request $request)
    { 
        if (!auth()->user()->canAccess('membership')) {
            return response()->json([
                'status' => 'error',
                'message'=> "Permission denied"
            ]);
        }

        $validator = Validator::make($request->all(),[
            'name' =>'required',
            'tittle' => 'nullable|string',
            'membership_id' => 'nullable',
            'tags' => 'nullable|array',
            'id' => "required_if:select_all,==,false|array",
            "prefference" => 'nullable',
        ],$customMessages);

        if($validator->fails()){
            return response()->json([
                'ststus'=>'error',
                'message' =>implode(',',$validator->errors()->all())
            ]);
        }

        $to = $request->ip_address;

        $transfer = [
            'status' => false,
            'lead_data' => []
        ];


        $filter_info_test = $request->ids;
        $filter_info = json_decode($filter_info_test, true);
        if($request->filled('select_all')) {
              $lead =Leads::where('id',$filter_info_test)->get();
            return response()->json($lead,200);
        }

Can you figure out what is it for or can you understand? After a couple of months do I have any clue what the heck is a get_view_container_new_user? No, I have no idea what it is. This project is about customer relationship management and leads but it does not reveal that intention.

And from a business point of view, the terms are not that much belong to technical like container get a view & I hope you ever hear a product manager saying wow, we got so much positive feedback on the get_view_container_new_user feature?

You may think if I take a step back and look at the file structure, you may have a better idea. The file structure

Nope, I think still you have no idea what is happing even if we have a document on each feature it's very hard to transfer the knowledge to a new developer who gets into the team.

So strategic design is all about not building projects like this one. The code base should be closer to the business terms. The DDD and technical design give you some valuable support in maintaining applications. To achieve this DDD has some concepts. They are

  • Value Objects

  • Data Transfer Objects

  • Repositories

  • Custom Query Builders

  • Services

  • Actions

  • View Models

  • CQRS

  • States and Transitions

  • Domains and Applications

All these above concepts can be used to achieve a domain-driven design architecture but there are not any strict rules to follow these are the guideline you choose any of the following concepts that suit your project & your team.

Basic Structure

The main idea of the DDD is to organize all the code related to a single domain inside a domain name. In Laravel, we can achieve that by simply adding some lines of code to composer.json the file . We are not building it as a package so, we don't need any new logic for scaffolding a default Laravel application and upgrading to a newer version is also easy.

Step 1 :

Add this line in a composer.json file.

 "autoload": {
        "psr-4": {
            "App\\": "app/",
            "Domain\\": "src/Domain",
            "Database\\Factories\\": "database/factories/",
            "Database\\Seeders\\": "database/seeders/"
        }
    },

Step 2 :

Run composer dump-autoload .

Step 3 :

Now create a new folder with a name src at the root of your project.

Step 4 :

Then inside src folder create a folder Domain where all the folders can be created for each domain with the following namespace. And inside each domain folder, we can place our Actions & Models & Services.

Conclusion

This article is to just give a basic idea about Domain Driven Design. There are a ton more things to cover & this is an article inspired by Martin Joo - Domain-Driven Design with Laravel.

That is one of the best books to learn about DDD on Laravel. I am not affiliated with him or promoting this book this is my personal thought. Please share & like

Feel free to share your inputs in the comments for improvements.

Did you find this article valuable?

Support Saravana sai blog by becoming a sponsor. Any amount is appreciated!