Is it bad practice to have validation in the application service that checks if a DTO's id is valid or if one of the dto's properties is blank?

Viewed 230

I have validation logic in my application service that determines whether the requested operation was a success and if not, the reason why. I question if this is a code smell since it's in the application service and not the domain service and it revolves around checking if a domain model exists, whether or not the property from the dto can be blank, etc. The code is below:

I do validation in the domain models such as when creating a new Event(). The constructor does basic validation for it's passed values such as the name cannot be null or empty. But when it comes to writing a test for this I start to question if the validation logic should be in a domain service that can be tested individually for validation. Then this method could be tested to make sure the dependencies are all called correctly. It makes me question if this is a leaking of the domain into the application layer or if this is considered application level logic. But at the same time, it isn't the domain's responsibility to take a DTO and validate the values, correct?

2 Answers

Although there are different views related to put Validation in which layer, I personally believe that only business rules should be checked in domain layer. Putting every validation in domain layer leads domain layer to wrong way. Domain layer is designed for business rules. Checking a property that just not to be empty is business rule? If no, it would be better to check it in application service layer.

As can be seen in Ordering service, which is a Microsoft sample project, this sort of validations is implemented in application layer. In this sample, CreateOrderCommand is like a DTO. FluentValidation is used in it. Due to Single Responsibility Principle, I recommend you to use this tool to separate validation process from your method and make testing much easier.

I usually ask the question Is it something the user could have done wrong or is something the developer implementing against the API could have done wrong?. By the latter I mean, the developer implementing against the API should not have allowed the user to send some incomplete request in the first place.

If your API strictly defines that a property has to be set (i.e. is mandatory) I would already verify this at the API or application layer. There is no need to pass this on to the domain layer. So if the developer who implemented against the API (e.g. in front-end code) forgot to make sure that the data sent corresponds to the specification an error should be raised already when receiving and processing the data from the REST call, message from a queue or whatever other communication protocol is used. I am of course talking about invariants that are not related to business logic at this level.

That does of course not mean that something similar will also be checked in the domain layer in some cases. Domain model classes should not allow to be constructed with invalid data so raising an error when invalid properties are received will also be the responsibility of the domain layer.

Checking against obvious errors before handing it over to the domain layer also adheres to the fail fast principle and might avoid unnecessary operations such as loading an aggregate from database to fail when calling a domain model operation that will fail because a parameter has not been passed properly with the request anyway.

Also consider, if this happens once there might not be much of an implication but consider there is some error in the client code you really can save a lot of resources on your side if lots of invalid calls would be made.

Is it bad practice to have validation in the application service that checks if a DTO's id is valid or if one of the dto's properties is blank?

So if you are not checking against business invariants but against invalid API specifications I say it is even good practice.

Related