Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clean architecture - where to put input validation logic? [closed]

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.

like image 565
Duy Pham Avatar asked Aug 22 '19 06:08

Duy Pham


People also ask

Where should input validation occur?

In general, it is best to perform input validation on both the client side and server side. Client-side input validation can help reduce server load and can prevent malicious users from submitting invalid data.

Is validation part of business logic?

Business logic tier validation assumes existing data is valid. The business logic tier employs validation logic when it needs to create or change data, but it assumes that data already in the table is valid.


3 Answers

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.
like image 167
Jemshit Iskenderov Avatar answered Oct 13 '22 12:10

Jemshit Iskenderov


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 layey, 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.

like image 22
Selmison Miranda Avatar answered Oct 13 '22 11:10

Selmison Miranda


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.

like image 1
Diego Avatar answered Oct 13 '22 10:10

Diego