[0:00] Hello guys, today I want to explain the [0:02] logic behind domain driven design with [0:05] examples of Laravel. And the term domain [0:07] driven design is not Laravel is not [0:10] about PHP. It's way outside of the [0:12] framework and programming language. It's [0:14] a term. It's a concept. And this is the [0:16] definition I found best on Reddit. Also, [0:19] another definition is by Martin Fowler. [0:22] It comes from 2020, but based on a book [0:24] from 2003. So, it's not a new concept. [0:28] its approach to software development [0:30] that centers on processes and rules of a [0:33] domain. What does that actually mean? So [0:36] for the last month or so I was trying to [0:38] explore experiment asking AI as well [0:41] because there are a lot of [0:42] interpretations of DDD specifically in [0:45] Laravel. You may find different examples [0:47] open source and tutorials with different [0:50] folder structure, different naming of [0:52] things, different approaches. So I was [0:54] thinking how to explain it and kind of [0:56] summarize it for people in simple [0:59] example because domain driven design is [1:02] not for simple projects. So how to [1:04] dissect it down and I think I succeeded [1:07] in a new course about Laravel modules [1:10] and DDD. So there is a oneh hour section [1:13] about domain driven design and in this [1:15] video I'll try to summarize it even more [1:17] for you with simple example in fact [1:20] three examples. We will go from simple [1:23] Laravel controller and validation and go [1:26] a few levels deep where that validation [1:28] should be stored until in the second [1:30] part of this video. I hope it would make [1:32] sense why DDD may be beneficial and what [1:36] problem it solves in projects and why it [1:39] is different from Laravel first [1:41] thinking. So in Laravel we first think [1:44] with controllers, routes, eloquent [1:46] models, migrations, form requests and [1:48] stuff like that. In DDD thinking is [1:51] totally different and let me explain [1:53] that in this video. So if we take a look [1:55] at a typical DDD structure inside of [1:57] Laravel application this is way outside [2:00] of Laravel terms. So we have application [2:03] with DTO's queries commands and stuff [2:05] like that. Then we have domain with [2:07] entities and some of the folders and the [2:10] names may be familiar to you in Laravel. [2:12] And then only on some layer we get to [2:15] controllers and eloquent models and [2:18] familiar structure with Laravel. And at [2:20] first it may look like a total overkill [2:23] to you, total overengineering. And in [2:25] most cases in fact it is. But let me try [2:28] to explain the way of thinking why that [2:30] structure may be beneficial if you start [2:32] with very small Laravel typical [2:35] controller. So let's start with a simple [2:37] example which probably everyone will be [2:39] familiar with. a typical Laravel [2:41] controller with validation in form [2:42] request and in store and update methods. [2:46] You have different form request classes [2:48] because the rules are a little bit [2:50] different for store and update and [2:53] inside of that store post request we [2:55] have rules for title content and slug in [2:59] the store request and then in the update [3:02] request the only difference is unique [3:04] which should ignore the current post ID [3:07] being updated. I think majority of [3:09] Laravel developers have done something [3:11] like that in their career. And this [3:13] approach is okay. It works. There's [3:15] nothing really wrong with that. You [3:17] could even potentially reuse those form [3:20] requests in another controller like API [3:23] controller. So I created specifically [3:25] postcontroller API with similar store [3:28] and update methods reusing the same form [3:31] request because form requests are in app [3:34] http requests. They are not related to [3:37] API or admin or web specifically. So [3:40] they are reusable which is great. But [3:43] the main problem with this approach is [3:45] that the logic of validation is in two [3:48] separate places. So imagine some [3:50] colleague from your team asks you could [3:52] you check what is the length the max [3:54] length of the post currently in our [3:56] system. Where do you go to check that? [3:59] You have store post request here and you [4:01] can find that the validation is max 150 [4:04] but you need to double check that with [4:07] update form request is it the same. So [4:09] you go to update post request and double [4:11] check that yeah it is 150. Of course you [4:14] can go to just create form request and [4:16] not check update form request. But then [4:18] you need to trust that no one made a [4:20] typo and mistake and those strings are [4:23] actually identical in two classes. [4:26] Similarly, for example, what if some [4:28] manager asks you to make content [4:30] optional? For example, when adding a [4:32] post, the title and the slug are [4:34] required because we're planning the [4:36] post, but the content could be written [4:38] later, right? So then that required [4:40] should be changed to optional. But then [4:42] you need to do that in two places in [4:44] update post request and install post [4:47] request twice. And of course, this is [4:50] easy if that is the code you wrote. So [4:52] you remember that is in two places or if [4:55] the code base is not that big. So you [4:57] have like five CRUDs typical simple blog [4:59] and then you remember everything or at [5:02] least you know that the logic is in [5:04] separate form requests. But imagine [5:06] you're working with a project with 50 [5:08] plus cruds with 10 or 20 developers and [5:12] you are asked the same questions about [5:14] validation for a module for a part of [5:17] application which you haven't seen [5:19] before. So you're working on internal [5:21] CRM for example and you don't touch the [5:24] blog ever in your day-to-day life but [5:26] someone from the team asks you to [5:28] quickly check that code. So then if the [5:30] logic is in two places, you may totally [5:33] miss one of those places or at least you [5:36] need to double check and be double [5:38] accurate and of course cover everything [5:40] with tests to not break anything. But [5:43] just the principle of logic in two [5:45] places then for bigger projects is a bad [5:49] practice. So a better approach to unify [5:51] the validation rules would be one form [5:54] request class you could call it post [5:56] request and then you provide the rules [5:58] and then add conditions depending on [6:01] where that request comes from from store [6:03] or update. So you have the route you can [6:06] check this also you can check for [6:08] example if there are other conditions [6:10] like for admin controller you have those [6:12] validation rules which do not appear in [6:14] the API for example. So then you add if [6:17] conditions, you may create private [6:19] methods here, but basically all the [6:21] logic to create or update a post is in [6:25] one file. Now don't get me wrong, the [6:28] separate files approach again is not a [6:30] bad thing for smaller projects. If you [6:33] remember that those are two files, but [6:35] if we're talking about bigger projects [6:37] and I'm getting to the DDD logic step by [6:40] step, one of the goals should be unified [6:42] set of rules somewhere. In this case, [6:45] for simple example, it's in form request [6:48] class. It's not DDD yet. Which leads me [6:50] to one step further. Form request is not [6:54] the best place to store that logic [6:56] because the request to create a post may [6:59] come not from the form and not from HTTP [7:02] like controller for create or update. It [7:05] may come from a cute job, automated [7:08] tests, artisan commands, some internal [7:11] service class and other parts of your [7:13] application. basically wherever and in [7:15] those places it's not easy to inject [7:17] form request class everywhere probably [7:20] possible in a hacky way but not ideal [7:24] form requests are usually for [7:25] controllers so then the question becomes [7:28] where do we put that logic and there are [7:30] various approaches but most of them lead [7:33] to some structure outside of typical [7:36] Laravel this is why bigger projects are [7:39] often Laravel kind of MVC layer but the [7:42] logic is inside of some service classes [7:45] or action classes or DTO's and all of [7:48] those are PHP classes not Laravel they [7:51] are just called from Laravel controllers [7:53] from routes and elsewhere but typically [7:55] you need to kind of stop thinking in [7:58] Laravel terms like how do I put [8:00] something in form request in eloquent [8:02] model or in controller and instead [8:04] define the structure somewhere in PHP [8:07] one of the ways is to define a service [8:10] class which is again PHP class there's [8:12] No artisan command php artisan make [8:14] service. There's a command php artisan [8:17] make class where you can put a service [8:19] in the name but that is php class. So in [8:22] that class you may do create an update [8:24] and inside that class you may have [8:27] validation. So then that service is [8:30] responsible for validation itself and if [8:32] validation fails it would throw PHP [8:35] exception. What happens with the [8:37] controllers then? So the controllers [8:39] could look something like this. You have [8:41] post service injected with constructor [8:44] property promotion and then you don't [8:46] work with eloquent or with form request. [8:49] You work with just service and then you [8:52] catch any exception that comes from that [8:55] service. If there's no exception then [8:57] you return the correct success result. [9:00] So then the controller becomes shorter [9:03] except for try catch. Maybe it may sound [9:05] longer but the logic is not in [9:08] controller and not in form request. It's [9:11] in kind of a black box which now can be [9:13] called from anywhere not necessarily [9:16] from a controller but that service could [9:18] be created the object of that service [9:20] created in a Q job in test again the [9:23] things that I mentioned. So now we moved [9:25] the logic even further from controller [9:27] to form request to service reusable [9:30] service and now all logic to create or [9:32] update the post is in one place reusable [9:36] and this is also one of the approaches [9:39] again there's no right or wrong here I'm [9:42] trying to explain just the theory why [9:44] the logic of the rules is moved from [9:47] controller to somewhere and now we'll [9:49] get to DDD but just kind of a side note [9:52] this is not the correct approach to [9:54] offload the logic. I'm just showing the [9:56] showcases and you may disagree with some [9: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