5

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.

Community
  • 1
  • 1
Denis Pshenov
  • 11,157
  • 6
  • 42
  • 42

1 Answers1

3

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.

jlvaquero
  • 8,571
  • 1
  • 29
  • 45
  • Throttling is to ensure that spammers can be contained. Also, is checking if comment contains spam links a domain concern? I would want this to happen regardless if it was in a web app, SOAP web service or a desktop app. Same goes for throttling. – Denis Pshenov Jan 20 '16 at 11:01
  • I think your answer is really good. It made me think about each requirement where I would ask myself "Will the domain be broken if this rule is not enforced?". So for most of them the answer is no. Domain is still intact if throttling, duplicate comments, dirty words, format, html tags or even authorisation is not enforced. Our application security, performance, friendliness, presentation might fail, but the domain will still be correct. Comments will still load and work just fine, albeit with rude words and ugly formatting. – Denis Pshenov Jan 20 '16 at 11:33
  • However, if we don't enforce that comments must belong to a real post or that comment must not be empty then this will quite likely break the domain. It is however not clear if domain will be broken if we allow to post to an unpublished post or a post where commenting has been closed. Technically speaking, everything will work just fine, domain will be in tact, but a business rule will be broken. What's your take on this? – Denis Pshenov Jan 20 '16 at 11:39
  • 2
    Your domain are the rules or viceversa. Breaking a rule is breakin the domain even if you don't get a error or exception in your application. I think that those rules enforcement belongs to the domain. Anyway, be careful with direct answers like this because I don't know the full context. – jlvaquero Jan 20 '16 at 12:07
  • @jlvaquero Email, persistence are most often classified as infrastructure services rather than application services. This article sums it up quite well : http://gorodinski.com/blog/2012/04/14/services-in-domain-driven-design-ddd/ – guillaume31 Jan 20 '16 at 12:34
  • @guillaume31 you are right. I just didn't want to add extra complexity into the answer. Great article BTW. Another good source about complete architecture that works well with DDD is http://jeffreypalermo.com/blog/the-onion-architecture-part-1/ where you can see how infraestructure is external and is injected into core. It is a personal taste of mine wrapping infraestructure into application features in the core and I thought it will simplifier the answer. – jlvaquero Jan 20 '16 at 12:48
  • Where would things such as XSS filter on comment content run? Is it domain? Because I would image that no matter what application was using this domain it would always need to have the XSS filter run on the content. But then again, this feels like security and security is not really domain concern. I wish this was simpler :) – Denis Pshenov Jan 20 '16 at 18:01
  • 2
    XSS? Its a web concern. Definitely not Domain. :) – jlvaquero Jan 20 '16 at 18:07
  • Right, what was I thinking. – Denis Pshenov Jan 20 '16 at 18:12