Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DDD: What goes into domain and what goes into application?

I find it difficult to decide whether something should be part of domain or application.

Reading through this answer helps a lot with concepts like authorisation but I still find myself struggling with other things.

To illustrate my confusion please consider a case of comment posting. Here are the things that need to happen before a comment can be posted. I indicate in parenthesis where I think this functionality should go.

  • Make sure user role/status is allowed to comment on this post (authorisation, goes to Application)
  • Make sure post to which we are commenting exists and is published (Domain)
  • Make sure user has not posted more than 5 comments in the last minute (throttling, intuition says it goes to Application)
  • Make sure comment is not an empty string (Domain)
  • Make sure comment does not have dirty words (Domain?)
  • Make sure comment does not have duplicates from same user in this post (Domain?)
  • Format the comment (Application)
  • Remove certain HTML tags from comment that are not permitted for current user (Application)
  • Check comment for spam (Application?)

I can't decide whether checking comment for spam is domain concern or application, same goes for throttling. From my point of view both of these concerns are important for me and must be present. But same goes for authorisation and we know that it should not be in Domain.

If I split these concerns between a domain service and application service then I feel like my domain is not completely enforced and actually relies on application to make prior checks. In that case what is the whole point, why don't I just do it all in application to reduce confusion?

My current setup does this:

Controller -> App.CommentingService.Comment() -> Domain.CommentingService.Comment()

It would be helpful if someone could go through all the required steps to create a comment and assign it to the right layer giving some reasoning behind.

like image 795
Denis Pshenov Avatar asked Oct 18 '22 17:10

Denis Pshenov


1 Answers

Your setup looks right. Application services often comes in 2 flavours:

Application features: Email notifications, Authorization, Persistence, etc. All the features, besides the domain, your system has comes here.

Application coordination: To meet a use case you need coordinate Application features and Domain. All the plumbing comes here.

Keep in mind that Application coordination models use cases so not always match 1 app service = 1 domain service because use case could involve more than 1 process.

 Controller 
     App.CommentingService.Comment() //coordination of below features and domain
         App.AuthService().Autorize(); //feature
         Domain.CommentingService.Comment(); //domain
         App.PersistenceService().Persist(); //feature
         App.NotificationService().SentNotificationToUser(); //feature

Why don't I just do it all in application to reduce confusion?

Resposibility segregation, loose coupling, dependency inyection, etc; all of this are good for many reasons. I will give you a real example I was involved recently: Having a loose couple assembly (it was in .NET framework) with just Domain services allows me to host the same Domain untouched in a Web app, a DesktopApp and a SOAP Web Service just changing the App coordination services because requirements and use cases are different on each app.

About what goes into domain and what not. It is very hard to give you a direct answer because it depends a lot of what is your domain or not.

i.e.

Make sure user has not posted more than 5 comments in the last minute

You have to question why are you throttling? To prevent a messy UI? Performance reason? Prevent Denial of service threat? Or is breaking a rule in your "game" because your "game" just gives limited tries to the user in a time spam? This is what indicates when something is Domain or Application.

like image 72
jlvaquero Avatar answered Oct 27 '22 10:10

jlvaquero