30

Perhaps in the app I have a feature allowing users to send feedback using a form with some validation logic:

  • name can be empty
  • feedback message should be at least 5 characters

Where would you put these validation logic, either in domain layer as business logic or in presentation layer as UI logic?

These logic are applied for all applications (android, iOS, web). Please note that we already had server side validation.

Jemshit
  • 9,501
  • 5
  • 69
  • 106
Duy Pham
  • 1,179
  • 1
  • 14
  • 19

3 Answers3

58

I think many developers do that in Presentation layer, specifically in ViewModel/Presenter/Controller (not in Activity/Fragment/View!). My approach is to put that logic in Domain layer. Why?

  • Is it presentation logic or domain logic? Presentation logic is something you decide "mapping render model", "format of render model", "how to render", "what color, what size, which text", "how long will it stay on screen" etc... If validation is presentation logic, why does backend code have same validation control? From my perspective, validation is Domain logic.
  • Why validation is Domain logic? Who decides if username can be 20 char at max? Business rule decides. Who decides number of max items in shopping basket? Business rule decides. The length of username is decision of business, and that rule applies in everywhere in the project. CreateProfile/ UpdateProfile/ Register etc.. all have same max-20char-username rule. That length control (validation) code should reside in Domain layer.
  • What is the flow if validation code is in Domain layer? User clicks button in View. ViewModel/Presenter calls domain layer function. Domain layer function validates input data. If there are invalid input parameters, it returns ValidationException with explanation. ValidationException will contain list of invalid parameters, type of validation they failed (minLength, maxLength, emailPatternMismatch etc..), what is expected (20 char at max etc..). ViewModel/Presenter/Controller gets this ValidationException and here we have Presentation logic. Now it decides what to render, how to render. Do we render error of all invalid inputs or only first invalid input? What text/color should be shown (based on data in ValidationException) ? Do we render error as popup/textView/tooltip? After all presentation decisions are made and new model is created, View just! renders using that model.
  • Another point is, in Domain layer, where should be validation code? In UseCase functions or in Models (why not) itself? IMHO, there should be Stateless Generic Interface/Class that has generic validation logics. And after that point, each UseCase class can implement ValidationInterface or inject it as Class object. If multiple UseCases need same validation, validation control logic will be duplicated. What happens if we put validation logic in Model itself? Model would implement ValidationInterface (which has stateless pure functions only!) and have fun validate():ValidationOutcome function. I don't think it is problem to put validation logic of Business Model in itself. All UseCases would call model.validate() only. There is dependency between Model and ValidationOutcome.
Jemshit
  • 9,501
  • 5
  • 69
  • 106
  • 4
    Insightful. Uncle Bob has said something similar in [one of the threads](https://groups.google.com/d/msg/clean-code-discussion/latn4x6Zo7w/bFwtDI1XSA8J) as well. :) – Sufian Jun 22 '20 at 06:24
  • Well explained. ValidationException drove the point home. – Myorh Mar 21 '21 at 06:55
  • 1
    from Uncle Bob's comment @Sufian mentioned and in the context of Clean Arch, each layer can/should have its own validation. So I think putting validation in Domain Layer does the validation for the domain but not for the presenter or entity. The example is that a customer comment length shouldn't be more than 100 characters, but the admin can go up to 1000 characters to answer. As in the clean architecture, we shouldn't change inner layers, by changing the outer layers, seems here we need validation in the presentation layer. – Sobhan Atar Jul 17 '21 at 08:23
20

I guess this example of Uncle Bob quoted by @sufian and this article can be useful when making that decision.

Naoto points out that just as Clean Architecture splits the responsibility by layers, each layer has its own validation logic.

In each layer, the system should reject the input which breaks its layer's responsibility. So the meaning of validation is differrent depending on its context.

In Application layer, as validation, we must ensure that domain objects can receive the input. We should reject the input which the domain object can't be received.

For example, when some mandatory parameters are missing, it should be rejected because the domain object has no way to receive like that parameter.

Sylvain Rodrigue
  • 4,751
  • 5
  • 53
  • 67
2

I'm not an android nor ios developer but I have some experience in web dev. This question is asked constantly by some coworkers. For me, the answer is both.

For example, if you have the validation logic in the presentation layer, whenever a user sends a bad input, you must go to the server, validate and then return the errors. To avoid asking the server you could validate the presentation layer with html5 or javascript. If some input is bad, this is shown to the user and there is no communication with the server (so you avoid one request). But this validation can be skipped easily, so if a user changes something or do the request with a tool (like postman) this validation doesn't happen. So, you can not be sure the data you are receiving is ok. For that, you need the server validation too.

For me, this is the safer solution and you only use UI to avoid bad request to the server.

Hope this helps.

user9088454
  • 1,076
  • 1
  • 15
  • 45
Diego
  • 89
  • 5
  • 1
    Agree that we should always have server side validation but what I was actually concerning is validation logic in client side to avoid redundant requests and have better UX that user don't need to wait for the api validation, it also reacts immediately when typing for example. – Duy Pham Aug 24 '19 at 03:01
  • 1
    Yes, i understand you. For me, an api should always have both types. An UX with validation (no server involved) and a server validation. Because you shouldn't trust 100% in the data the front or UX is sending to your server. So the answer would be to put the validation login in server and UX. – Diego Aug 25 '19 at 09:55
  • 1
    I think this answer is a bit outdated. Lots of front end application have a UI layer and a domain layer (in the front end itself). The question was where to put the validation inside the front end, not being concerned by the backend at all. – Ced Jul 19 '22 at 10:25