TubeSum ← Transcribe a video

Domain-Driven Design in Laravel: My Interpretation with Examples

Transcribed Jun 14, 2026 Watch on YouTube ↗
Intermediate 10 min read For: Laravel developers with some experience who want to understand Domain-Driven Design and its application in larger projects.
13.0K
Views
464
Likes
41
Comments
6
Dislikes
3.9%
📈 Moderate

AI Summary

This video explains the logic behind Domain-Driven Design (DDD) using Laravel examples. It emphasizes that DDD is a concept independent of Laravel or PHP, focusing on business rules and domain logic first. The speaker demonstrates how to move validation from controllers to reusable services and ultimately to domain entities, highlighting the benefits for larger projects.

[0:00]
Introduction to DDD

DDD is a concept not tied to Laravel or PHP; it's a philosophy centered on business rules and domain logic.

[0:28]
DDD Definition

DDD is an approach to software development that focuses on the processes and rules of a domain, based on a 2003 book.

[1:41]
Laravel vs DDD Thinking

Laravel thinking starts with controllers, routes, and Eloquent models, while DDD starts with domain logic and entities.

[2:46]
Problem with Duplicate Validation

Having separate form requests for store and update leads to duplicated validation rules, which is problematic in large projects.

[5:51]
Unified Validation Approach

Using a single form request with conditions for store/update reduces duplication and centralizes logic.

[6:50]
Moving Logic to Service Classes

Form requests are tied to HTTP; for reusability across queues, commands, and tests, validation should be in service classes.

[10:20]
DDD Entities

In DDD, business rules are encapsulated in domain entities (PHP classes, not Eloquent models), which are designed first.

[14:00]
Ubiquitous Language

DDD promotes a common language between developers and business stakeholders, making the code understandable by all parties.

[15:00]
DDD Overkill for Small Projects

DDD is often overkill for small projects but beneficial for large projects with many entities and developers.

[16:12]
DDD Opens Career Opportunities

Understanding DDD can lead to jobs at bigger companies and with other technologies, as it's a sought-after skill.

DDD is a powerful approach for large, complex projects, emphasizing business logic first and a ubiquitous language. While it may seem like overkill for small projects, learning DDD can improve code maintainability and open career opportunities.

Clickbait Check

90% Legit

"Title accurately reflects content: the video delivers a clear interpretation of DDD with Laravel examples."

Mentioned in this Video

Tutorial Checklist

1 2:37 Start with a typical Laravel controller with validation in form requests (store and update).
2 5:51 Unify validation rules into a single form request with conditions for store/update.
3 8:10 Move validation logic to a service class (PHP class) that can be reused across controllers, queues, and tests.
4 10:20 Design domain entities (PHP classes) that encapsulate business rules and validation, independent of Laravel.
5 11:52 Implement the entity with properties, value objects, and methods that enforce business rules (e.g., submit).

Study Flashcards (8)

What does DDD stand for?

easy Click to reveal answer

Domain-Driven Design

What is the core focus of DDD?

easy Click to reveal answer

Business rules and domain logic, not the framework or programming language.

0:28

What is a key problem with having separate form requests for store and update in large projects?

medium Click to reveal answer

Duplication of validation rules, making maintenance error-prone.

3:45

Why should validation logic not be in form requests for reusability?

medium Click to reveal answer

Form requests are tied to HTTP; logic may be needed in queues, commands, or tests.

6:50

What is a domain entity in DDD?

medium Click to reveal answer

A PHP class that encapsulates business rules and validation, independent of the framework.

10:20

What is 'ubiquitous language' in DDD?

hard Click to reveal answer

A common language between developers and business stakeholders, making code understandable by all parties.

14:00

Is DDD suitable for small projects?

easy Click to reveal answer

No, it is often overkill for small projects but beneficial for large, complex projects.

15:00

What career benefit does learning DDD provide?

medium Click to reveal answer

It opens opportunities at bigger companies and with other technologies, as it's a sought-after skill.

17:38

💡 Key Takeaways

📊

DDD Definition

Provides a clear, concise definition of DDD from a reputable source (Martin Fowler).

0:28
💡

Laravel vs DDD Thinking

Highlights the fundamental shift in mindset required for DDD.

1:41
🔧

Problem with Duplicate Validation

Illustrates a common pain point in Laravel projects that DDD addresses.

3:45
⚖️

Domain Entities

Explains the core concept of DDD entities as the heart of business logic.

10:20
💡

DDD Opens Career Opportunities

Provides practical motivation for learning DDD beyond project needs.

17:38

✂️ Creator Tools: Viral Hooks

AI-generated clip ideas for Shorts based on the transcript

What is Domain-Driven Design?

45s

Explains a complex concept in simple terms, appealing to developers curious about DDD.

▶ Play Clip

Laravel vs DDD: Different Thinking

60s

Highlights the contrast between typical Laravel development and DDD, sparking debate.

▶ Play Clip

The Problem with Duplicate Validation

60s

Relatable pain point for developers, showing why DDD matters in large projects.

▶ Play Clip

Moving Logic to a Service Class

60s

Demonstrates a practical refactoring step, making DDD less intimidating.

▶ Play Clip

DDD Entities: The Sacred Core

60s

Reveals the heart of DDD with a concrete example, making the concept tangible.

▶ Play Clip

[00:00] Hello guys, today I want to explain the

[00:02] logic behind domain driven design with

[00:05] examples of Laravel. And the term domain

[00:07] driven design is not Laravel is not

[00:10] about PHP. It's way outside of the

[00:12] framework and programming language. It's

[00:14] a term. It's a concept. And this is the

[00:16] definition I found best on Reddit. Also,

[00:19] another definition is by Martin Fowler.

[00:22] It comes from 2020, but based on a book

[00:24] from 2003. So, it's not a new concept.

[00:28] its approach to software development

[00:30] that centers on processes and rules of a

[00:33] domain. What does that actually mean? So

[00:36] for the last month or so I was trying to

[00:38] explore experiment asking AI as well

[00:41] because there are a lot of

[00:42] interpretations of DDD specifically in

[00:45] Laravel. You may find different examples

[00:47] open source and tutorials with different

[00:50] folder structure, different naming of

[00:52] things, different approaches. So I was

[00:54] thinking how to explain it and kind of

[00:56] summarize it for people in simple

[00:59] example because domain driven design is

[01:02] not for simple projects. So how to

[01:04] dissect it down and I think I succeeded

[01:07] in a new course about Laravel modules

[01:10] and DDD. So there is a oneh hour section

[01:13] about domain driven design and in this

[01:15] video I'll try to summarize it even more

[01:17] for you with simple example in fact

[01:20] three examples. We will go from simple

[01:23] Laravel controller and validation and go

[01:26] a few levels deep where that validation

[01:28] should be stored until in the second

[01:30] part of this video. I hope it would make

[01:32] sense why DDD may be beneficial and what

[01:36] problem it solves in projects and why it

[01:39] is different from Laravel first

[01:41] thinking. So in Laravel we first think

[01:44] with controllers, routes, eloquent

[01:46] models, migrations, form requests and

[01:48] stuff like that. In DDD thinking is

[01:51] totally different and let me explain

[01:53] that in this video. So if we take a look

[01:55] at a typical DDD structure inside of

[01:57] Laravel application this is way outside

[02:00] of Laravel terms. So we have application

[02:03] with DTO's queries commands and stuff

[02:05] like that. Then we have domain with

[02:07] entities and some of the folders and the

[02:10] names may be familiar to you in Laravel.

[02:12] And then only on some layer we get to

[02:15] controllers and eloquent models and

[02:18] familiar structure with Laravel. And at

[02:20] first it may look like a total overkill

[02:23] to you, total overengineering. And in

[02:25] most cases in fact it is. But let me try

[02:28] to explain the way of thinking why that

[02:30] structure may be beneficial if you start

[02:32] with very small Laravel typical

[02:35] controller. So let's start with a simple

[02:37] example which probably everyone will be

[02:39] familiar with. a typical Laravel

[02:41] controller with validation in form

[02:42] request and in store and update methods.

[02:46] You have different form request classes

[02:48] because the rules are a little bit

[02:50] different for store and update and

[02:53] inside of that store post request we

[02:55] have rules for title content and slug in

[02:59] the store request and then in the update

[03:02] request the only difference is unique

[03:04] which should ignore the current post ID

[03:07] being updated. I think majority of

[03:09] Laravel developers have done something

[03:11] like that in their career. And this

[03:13] approach is okay. It works. There's

[03:15] nothing really wrong with that. You

[03:17] could even potentially reuse those form

[03:20] requests in another controller like API

[03:23] controller. So I created specifically

[03:25] postcontroller API with similar store

[03:28] and update methods reusing the same form

[03:31] request because form requests are in app

[03:34] http requests. They are not related to

[03:37] API or admin or web specifically. So

[03:40] they are reusable which is great. But

[03:43] the main problem with this approach is

[03:45] that the logic of validation is in two

[03:48] separate places. So imagine some

[03:50] colleague from your team asks you could

[03:52] you check what is the length the max

[03:54] length of the post currently in our

[03:56] system. Where do you go to check that?

[03:59] You have store post request here and you

[04:01] can find that the validation is max 150

[04:04] but you need to double check that with

[04:07] update form request is it the same. So

[04:09] you go to update post request and double

[04:11] check that yeah it is 150. Of course you

[04:14] can go to just create form request and

[04:16] not check update form request. But then

[04:18] you need to trust that no one made a

[04:20] typo and mistake and those strings are

[04:23] actually identical in two classes.

[04:26] Similarly, for example, what if some

[04:28] manager asks you to make content

[04:30] optional? For example, when adding a

[04:32] post, the title and the slug are

[04:34] required because we're planning the

[04:36] post, but the content could be written

[04:38] later, right? So then that required

[04:40] should be changed to optional. But then

[04:42] you need to do that in two places in

[04:44] update post request and install post

[04:47] request twice. And of course, this is

[04:50] easy if that is the code you wrote. So

[04:52] you remember that is in two places or if

[04:55] the code base is not that big. So you

[04:57] have like five CRUDs typical simple blog

[04:59] and then you remember everything or at

[05:02] least you know that the logic is in

[05:04] separate form requests. But imagine

[05:06] you're working with a project with 50

[05:08] plus cruds with 10 or 20 developers and

[05:12] you are asked the same questions about

[05:14] validation for a module for a part of

[05:17] application which you haven't seen

[05:19] before. So you're working on internal

[05:21] CRM for example and you don't touch the

[05:24] blog ever in your day-to-day life but

[05:26] someone from the team asks you to

[05:28] quickly check that code. So then if the

[05:30] logic is in two places, you may totally

[05:33] miss one of those places or at least you

[05:36] need to double check and be double

[05:38] accurate and of course cover everything

[05:40] with tests to not break anything. But

[05:43] just the principle of logic in two

[05:45] places then for bigger projects is a bad

[05:49] practice. So a better approach to unify

[05:51] the validation rules would be one form

[05:54] request class you could call it post

[05:56] request and then you provide the rules

[05:58] and then add conditions depending on

[06:01] where that request comes from from store

[06:03] or update. So you have the route you can

[06:06] check this also you can check for

[06:08] example if there are other conditions

[06:10] like for admin controller you have those

[06:12] validation rules which do not appear in

[06:14] the API for example. So then you add if

[06:17] conditions, you may create private

[06:19] methods here, but basically all the

[06:21] logic to create or update a post is in

[06:25] one file. Now don't get me wrong, the

[06:28] separate files approach again is not a

[06:30] bad thing for smaller projects. If you

[06:33] remember that those are two files, but

[06:35] if we're talking about bigger projects

[06:37] and I'm getting to the DDD logic step by

[06:40] step, one of the goals should be unified

[06:42] set of rules somewhere. In this case,

[06:45] for simple example, it's in form request

[06:48] class. It's not DDD yet. Which leads me

[06:50] to one step further. Form request is not

[06:54] the best place to store that logic

[06:56] because the request to create a post may

[06:59] come not from the form and not from HTTP

[07:02] like controller for create or update. It

[07:05] may come from a cute job, automated

[07:08] tests, artisan commands, some internal

[07:11] service class and other parts of your

[07:13] application. basically wherever and in

[07:15] those places it's not easy to inject

[07:17] form request class everywhere probably

[07:20] possible in a hacky way but not ideal

[07:24] form requests are usually for

[07:25] controllers so then the question becomes

[07:28] where do we put that logic and there are

[07:30] various approaches but most of them lead

[07:33] to some structure outside of typical

[07:36] Laravel this is why bigger projects are

[07:39] often Laravel kind of MVC layer but the

[07:42] logic is inside of some service classes

[07:45] or action classes or DTO's and all of

[07:48] those are PHP classes not Laravel they

[07:51] are just called from Laravel controllers

[07:53] from routes and elsewhere but typically

[07:55] you need to kind of stop thinking in

[07:58] Laravel terms like how do I put

[08:00] something in form request in eloquent

[08:02] model or in controller and instead

[08:04] define the structure somewhere in PHP

[08:07] one of the ways is to define a service

[08:10] class which is again PHP class there's

[08:12] No artisan command php artisan make

[08:14] service. There's a command php artisan

[08:17] make class where you can put a service

[08:19] in the name but that is php class. So in

[08:22] that class you may do create an update

[08:24] and inside that class you may have

[08:27] validation. So then that service is

[08:30] responsible for validation itself and if

[08:32] validation fails it would throw PHP

[08:35] exception. What happens with the

[08:37] controllers then? So the controllers

[08:39] could look something like this. You have

[08:41] post service injected with constructor

[08:44] property promotion and then you don't

[08:46] work with eloquent or with form request.

[08:49] You work with just service and then you

[08:52] catch any exception that comes from that

[08:55] service. If there's no exception then

[08:57] you return the correct success result.

[09:00] So then the controller becomes shorter

[09:03] except for try catch. Maybe it may sound

[09:05] longer but the logic is not in

[09:08] controller and not in form request. It's

[09:11] in kind of a black box which now can be

[09:13] called from anywhere not necessarily

[09:16] from a controller but that service could

[09:18] be created the object of that service

[09:20] created in a Q job in test again the

[09:23] things that I mentioned. So now we moved

[09:25] the logic even further from controller

[09:27] to form request to service reusable

[09:30] service and now all logic to create or

[09:32] update the post is in one place reusable

[09:36] and this is also one of the approaches

[09:39] again there's no right or wrong here I'm

[09:42] trying to explain just the theory why

[09:44] the logic of the rules is moved from

[09:47] controller to somewhere and now we'll

[09:49] get to DDD but just kind of a side note

[09:52] this is not the correct approach to

[09:54] offload the logic. I'm just showing the

[09:56] showcases and you may disagree with some

[09:58] of those and you may probably not do

[10:01] exactly like this in real life scenario

[10:03] but this is just an example and with

[10:05] that example kind of the wrong thing or

[10:08] maybe not ideal thing is that service

[10:11] class is responsible for eloquent model.

[10:15] Couldn't eloquent model itself be

[10:17] responsible for well itself? And this is

[10:20] where we get to ddd to domain driven

[10:23] design. And here you need to understand

[10:26] basically all three words domain driven

[10:27] and design. So let me explain in a

[10:29] minute. Domain is too fancy word to be

[10:32] honest. I don't like it because domain

[10:33] is even ambiguous. It could mean a web

[10:35] domain like.com. But domain you can call

[10:38] it business logic or business rules. So

[10:41] the application is driven. So domain

[10:43] driven driven by business rules and

[10:46] business logic first. which means that

[10:48] the project is started being created

[10:51] from business rules by business people

[10:54] as well. So the goal is to define the

[10:56] business rules behind the post later

[10:58] eloquent model but it's just an object

[11:01] it's called entity. So business people

[11:03] should provide the specification or it

[11:05] could be done with collaboration with

[11:06] developers. What can happen with that

[11:08] post entity? Can it be created? Can it

[11:11] be updated? What are the validation

[11:13] rules? What happens when the post is

[11:15] actually published and stuff like that?

[11:16] This should be in specification on paper

[11:19] markdown, Google Doc, GitHub issue or

[11:22] whatever documentation system and then

[11:24] it is transformed into the code in PHP

[11:27] language in this case with the idea that

[11:30] anyone who would consume that logic

[11:32] those rules it may be laravel it may be

[11:35] symfony it may be whatever else the

[11:37] logic is to design and this is where

[11:40] third word comes in domain driven design

[11:42] the logic and the idea and the goal is

[11:44] to design that entity

[11:47] to contain maximum amount of rules in

[11:50] itself. So let me show you the example

[11:52] from my course about university

[11:54] management system and this is one of the

[11:57] layers of that so-called bounded

[12:00] context. It's almost the same as module

[12:03] but here we have domain folder and here

[12:05] we have entities and for example one of

[12:08] the entities is student application and

[12:11] again this is one of the interpretations

[12:14] of DDD more like example so you would

[12:17] understand the concept inside of that

[12:19] student application class which is PHP

[12:22] not eloquent model not migration nothing

[12:25] from Laravel at all so this class

[12:28] doesn't know anything about Laravel or

[12:31] eloquent and this class is actually the

[12:33] first thing that you create in DDD

[12:36] project. So you don't start with Laravel

[12:39] new, you don't start with routes and

[12:40] controllers, you start with domain

[12:43] logic. So that's why domain driven

[12:45] design and this is what I would call the

[12:47] specification the project requirement

[12:50] just transformed into PHP language. So

[12:54] you have all the properties with their

[12:56] types with their validation required or

[12:58] not with some specific so-called value

[13:02] objects. If the rules are more

[13:04] complicated than float or string, you

[13:06] may have other entities. So for example,

[13:08] you have student entity inside of

[13:10] student application which then makes

[13:12] student application kind of on higher

[13:14] level so-called aggregate root. And then

[13:17] when constructing that object, that

[13:20] entity, this is where you put in the

[13:23] validation most of it. So if something

[13:25] is wrong at the time of creating that

[13:28] object wherever that creating of the

[13:30] object happens it may happen later in

[13:32] Laravel or in some other layer of DDD

[13:35] structure but this is kind of the final

[13:39] validation logic the ultimate place

[13:41] where all the business rules are written

[13:44] here about the student application in

[13:47] this case but in case of post model that

[13:50] we saw earlier this would be the entity

[13:52] of post and And also in that entity you

[13:55] define what can happen with that entity.

[13:58] In this case student application can be

[14:00] submitted. And this is another thing

[14:02] about DDD. One of the other goals with

[14:06] domain driven design is the language and

[14:08] the words and the naming of pretty much

[14:12] everything. So for example class of

[14:14] student application cannot be really

[14:16] called application because it's

[14:18] ambiguous. It should be student

[14:19] application. One of the ideas is that

[14:22] business guys like CEO or project

[14:24] managers could technically look at the

[14:27] code and still understand all the

[14:29] concepts. Sometimes you may hear the

[14:31] word ubiquitous language as one of the

[14:33] goals of DDD which means that the logic

[14:36] again the business logic the business

[14:38] layer rules are defined first and

[14:41] understandable by all parties all

[14:43] developers all business layer guys and

[14:46] this is kind of the bible of that

[14:48] application whatever comes next in the

[14:51] next layers of ddd lower there are

[14:53] services repositories and then at some

[14:56] point we get to eloquent models and

[14:58] controllers much much later. And if you

[15:00] haven't tried domain driven design and

[15:02] you work with kind of a regular Laravel

[15:04] developer and you think that this whole

[15:06] structure is a big overkill, in most

[15:09] cases it is. But again, we're talking

[15:11] about bigger project. Imagine 50

[15:14] entities, 10 to 20 developers and

[15:17] different departments working on

[15:19] different parts of the application. But

[15:21] still all the business rules should be

[15:23] manageable in kind of one place or in

[15:27] one layer which is actually the domain

[15:29] layer and the entities are kind of the

[15:32] most sacred part of domain driven design

[15:35] and that structure is of course not

[15:37] typical to Laravel because domain driven

[15:40] design is not about Laravel. It's not

[15:42] about even PHP. It's a general

[15:44] philosophy like object-oriented

[15:46] programming or similar which you can

[15:48] apply to basically any programming

[15:50] language and also there are a lot of

[15:52] interpretation as I mentioned about DDD

[15:55] so that's why if you Google DDD

[15:57] especially in Laravel there are various

[15:59] folder structures because DDD is not

[16:02] about folders specifically there are

[16:04] various ways to skip some layers in the

[16:07] structure or add some layer or maybe

[16:09] name the layer differently sometimes and

[16:12] here I want to quote one tweet, one

[16:14] reply to my own tweet. When I was

[16:16] working on that course on DDD, I

[16:18] realized that you have to zoom out and

[16:20] think way outside of Laravel to

[16:23] understand DDD. I hope I explained it in

[16:25] this video, but Joseph replied with very

[16:28] profound thing. If in your project you

[16:31] want domain driven design, you might not

[16:33] really need Laravel or in other words

[16:36] Laravel becomes smaller layer of your

[16:39] whole application which comes as I said

[16:42] in this video much later to consume the

[16:45] structure of the business domain. And

[16:47] here's another tweet I want to quote. If

[16:49] you think that DDD is not for you, look

[16:52] at the tweet by Mark. wasn't really a

[16:54] fan of modules and DDD until someone

[16:57] implemented it and then much later it

[17:00] starts clicking, it starts working and

[17:02] then everything is easier to know where

[17:05] everything was. So this is one kind of

[17:08] motivation to maybe consider DDD for

[17:10] your next project if it's big right off

[17:13] the gate to design the project again

[17:15] domain driven design to design the

[17:17] project structure in a way so it would

[17:19] be manageable later in a year or in two

[17:22] years by different teams with maybe even

[17:25] different business management people

[17:27] that domain driven design may help with

[17:29] that for long term of the project and

[17:32] the final thing kind of a motivation if

[17:34] you think that DTD is not for you look

[17:36] at says another tweet by Uladimir. The

[17:38] logic is this. Since DDD is not about

[17:41] Laravel or PHP, DDD may open the gate

[17:45] for you to get other jobs from other

[17:47] technologies not necessarily in Laravel

[17:50] and also it may open the gate for you to

[17:53] work at bigger companies at more serious

[17:56] projects. Here are a few examples of

[17:58] jobs mentioned by Uladimir here and

[18:01] let's open a few of them randomly. So

[18:04] senior PHP developer as you can see it's

[18:06] not about Laravel and let's zoom in and

[18:09] one of the responsibilities is maintain

[18:12] highquality PHP applications and one of

[18:15] the requirements is domain driven design

[18:18] another example backend PHP Laravel

[18:20] about the job see more this is in

[18:23] Spanish language but the keyword DDD is

[18:26] present and specifically hexagonal

[18:28] architecture which is another separate

[18:30] topic but basically this is part of a

[18:33] job requirement. So yeah, if you don't

[18:35] need DDD specifically on your projects

[18:37] because they are smaller projects at the

[18:39] moment, you may want to dive into it to

[18:42] at least understand the logic and the

[18:45] use cases to be able to work on bigger

[18:47] projects more easily and not get lost in

[18:50] the future. And for that I do recommend,

[18:53] of course, I'm biased here, but my new

[18:55] course about Laravel modules and DDD,

[18:57] the second part of that course is about

[18:59] DDD specifically. So one hour for

[19:01] modules and one hour for DDD kind of

[19:04] comparing the approaches. So over those

[19:07] videos I explained the logic behind

[19:09] other layers of that folder structure

[19:11] that you saw in this video. Again it's a

[19:13] simplified example. It's personal

[19:15] interpretation of DDD but with the goal.

[19:18] So you would understand the logic, the

[19:20] goal and the way of thinking in domain

[19:23] driven design terms which is not typical

[19:26] to Laravel. I hope in this video I gave

[19:28] you at least some motivation to at least

[19:30] explore more serious structure like DDD.

[19:34] But of course, as usual, we can discuss

[19:36] in the comments below. My interpretation

[19:38] may be just my interpretation and we can

[19:40] talk about that in the comments below.

[19:43] That's it for this time and see you guys

[19:44] in other

⚡ Saved you time reading this? Transcribe any YouTube video for free — no signup needed.