Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
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.
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.
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.
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.
Related
I have a question about responsibility of Controller and service about a piece of my code. I have a HTML form to save an article which can submit three image(thumbnail, summary and body) with their text. The body text can contains some images in Base64 format. I get them by a post Action which accept a DTO object to support all inputs.
The Tasks I want to do are:
Get DTO from client
Fetch images from body
Check Summary and body text rules
Check Fetched images rules
Check Thumbnail, summary and body image rules
Save them
I have a service layer here which has some class about checking article texts and images logics.
My question is that how should I act here. Which steps are for Controller and which ones for Service.
Step 2 is most confusing step to me. Should I do it in controller or just pass all DTO to Service to separate things itself?
Or about checking text, should I check for example summary text length in controller or it should be check by Service layer?
Can any one explain these to me?
Possible duplicate.
The responsibility of the controller, is to accept a request, invoke the processing, and respond according to the result of the processing.
Try to look at the SOLID principles and always try to apply them.
So first of all, DTO, it depends on your architectural design, but I would say that the DTO is the abstraction that allows you to decouple you Domain Model from the client model.
The DTO should be seen as the data representation between two layers, if the DTO crosses more than one layer, it probably isn't a DTO but a business or data entity.
) Fetch images from body
this looks like something you designed to be able to receive the desired data, but is not something your domain model cares about.
For example if your form allow you to save "Sale advert", which is made of few images and some text, probably this aggregation of data in your business layer (service), is represented by one or more domain objects, so the fact that you receive a body in whichever format, depends more on technology or transport, and should be transparent to your business layer.
A good example to help you find boundaries, is thinking about re-usability. How would you reuse your service layer if you were to use it from a WCF service for example?
Your service should always receive and expose Domain Objects.
Leave to the consumer component the responsibility to decode/encode.
3) Check Summary and body text rules (and all other checks)
seems to be a validation, but I cannot tell if this validation is only related to the domain.
Some validation is also done in the controller itself to check if the request is valid or not.
So if this check is done on the DTO structure, before you try to convert it, probably that is a controller validation, if instead, this validation is necessary to decide weather or not the input can be saved, well probably in this case it would be considered other's responsibility.
You mentioned:
for example summary text length
if this is a business rule, then I would place it in a validation object, responsible to validate the "summary text" or let's call it again "Sale advert".
The responsibility to save a domain object to a data store, is normally delegated to a Data Access Layer, which is coupled to the database structure and provides the abstraction to the business layer.
This can be done implementing a repository pattern or maybe using an ORM, I normally don't add logic to persist data in the business layer.
Another note, here you are asking about controller responsibility, but pay attention to your service "layer", I have seen often code where a huge service class, was encapsulating all the business logic and validation, that is very bad because again goes against most of the solid principles.
Look at the command query and decorator pattern, I love them because the really help you breaking down your code in smaller pieces with single responsibility.
If interest look at this example project on github (.net core).
I am still working on the documentation but should be clear enough.
I have question about MVP. If presenter sends request to model for data. Does model check these data or does presenter have to do it? For example: are data ok etc. Thank you for answers.
I think there are a couple approaches you can take to validate your data: Either the Domain objects or a Service.
You model is your domain. In domain driven development, your domain should know how to validate itself. So, you might have a standard Validate method on either class in the model. That can get a little tricky, though, if you need to make a database call to do the validation, although you could require the relevant data to be passed to your validation method, or provide a delegate to get the data if it's necessary.
Alternatively, you could put all the validation in the Service later, which your presenter would be calling to retrieve and to persist the model. This would result in the so-called antipattern "anemic domain". But, if that fits your application and architecture best, it might be the correct choice.
I would caution against having the presenter do it. That's not really it's job and it does not get reused like the model and service.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I am working on a web application in spring following the MVC pattern and was wondering what is considered "best practice" for making a solid service layer. The reason for this question is the following example situation:
A page for editing user information is loaded. After this form is submitted I gather all of its data in my controller method in a specific Command class containing only the data needed for the action that follows (updating the user).
I can think of several situations now to pass this information to my service layer:
Passing the command itself: userService.save(command);
Passing a model class, fetched in the controller: userService.save(user);
Passing both a model class and the command: userService.save(user, command);
Passing all of the parameters individually: userService.save(command.getName(), ...)
In my opinion passing the command class itself looks like the most elegant solution as I can first validate all the values automatically using the framework then pass them to my service. My concern here is that when I call the method from another class (not through my form / controller) I can fill this command object with invalid data, resulting in possible errors in the service layer.
What would you recommend and why?
After seeing your I have the following ideas
Passing the command itself: userService.save(command);
This may not be a goode idea since your Service layer is unnecessarily
dependent on Command object
Passing a model class, fetched in the controller: userService.save(user);
I will vote for this. Service layer only what it really supposed to
know
Passing both a model class and the command: userService.save(user, command);
No. Same as the first option
Passing all of the parameters individually: userService.save(command.getName(), ...)
Hmmmm... not sure.. May be a mainitenance overhead in future.
I think if you want to do the validation, Use validation util classes to do the validation
which can be used for both Service and UI layer. Here a lot validation can be centralized.
In his MVC book, Dino Esposito recommends creating a 'worker' class that takes and returns a viewmodel. The controller calls the worker with the viewmodel and then the worker delegates as necessary. I've not used it in practise but in theory it appears to be a nice solution.
Any option using your Command object will cause trouble. It breaks loose coupling. Now your service layer is tightly coupled with service layer. Please don't do it.
(EDIT: In my answer below, when I say Model for presentation layer I am talking about View Model and for service layer it is the Domain Model)
Sending your Model object looks like a good option. But, it depends on how the model was created. Some times, presentation layer will need a different model structure and the service layer will need a moderatley/completely different structure.
If both layers have different needs, then you need to create 2 model structure. This way service layer's model structure doesn't have to change when presentation layer changed. This is important as the service may have multiple consumers and may not be able to change when presentation layer changes.
If they don't have different structure, I would still create them from service layer point of view as service is the real reusable component here.
A good pattern to follow when dealing with commands in multi-layered systems is to have a CommandBus service that routes your commands to their specific handlers. That way, you decouple your controller from your services (while coupling it with a generic routing system).
commandBus.handle(command);
You must do additional work in configuring the command bus handlers, but it will pay in the long term when you'll be able to reuse that routing information:
commandBus.register(commandType, handlerService);
and you may then be able to move the validation of the commands in the commandBus service (even though this will mean some mixing of concerns for the commandBus)
commandBus.registerValidator(commandType, validatorsCollection);
I have been reading about specifications lately and I am really keen on using them. However, I am afraid to overdo it.
For example, if I have a User entity with a phone number property, do I need to put the phone number specification test in the setter, or is the validation logic in the setter enough?
Thanks,
Phil
UPDATE:
For more context:
I think I would like the validation to be in the domain, and not in the presentation. I will implement the validation in presentation, but that will be more of a UI feature. The idea (i believe) is that the domain cannot be in an invalid state, nor can it rely on the presentation. I actually have a phone number Entity, and many entities have phone numbers, though I suppose this could value object, but that is another debate:)
I was just wondering if it overkill to use Specifications in Property setters. One advantage I could see is that Specifications can be shared between layers, ie the Presentation Layer, so that you can share the validation code.
As you can see, I am unsure if this is the right approach.
Much Thanks,
Phil
You might look into the notion of pre and post conditions (invariants or design by contract).
Pre conditions are things that must be true for your function to operate correctly.
Post conditions are things that will be true when your function is complete and exits normally.
"user's phone number valid" is probably a good post condition to have for your setter function. However you have 2 choices for the pre-condition: (1) make it a precondition of your setter function that whatever is passed to it is valid, or (2) make a much looser pre condition to your setter function and perform the error checking in your setter function. Option (1) essentially passes responsibility for validation to the client. Option (2) endows your User entity with the responsibility for error handling.
I think the design you choose would depend on the bigger picture for your specific application.
Here are a few links for invariants and design by contract:
http://svengrand.blogspot.com/2008/11/preconditions-postconditions-invariants.html
http://en.wikibooks.org/wiki/Computer_Programming/Design_by_Contract
In coding a traditional MVC application, what is the best practice for coding server-side form validations? Does the code belong in the controller, or the model layer? And why?
From Wikipedia:
Model-view-controller (MVC) is an architectural pattern used in software engineering. Successful use of the pattern isolates business logic from user interface considerations, resulting in an application where it is easier to modify either the visual appearance of the application or the underlying business rules without affecting the other. In MVC, the model represents the information (the data) of the application and the business rules used to manipulate the data; the view corresponds to elements of the user interface such as text, checkbox items, and so forth; and the controller manages details involving the communication to the model of user actions such as keystrokes and mouse movements.
Thus, model - it holds the application and the business rules.
I completely agree with Josh. However you may create a kind of validation layer between Controller and Model so that most of syntactical validations can be carried out on data before it reaches to model.
For example,
The validation layer would validate the date format, amount format, mandatory fields, etc...
So that model would purely concentrate on business validations like x amount should be greater than y amount.
My experience with MVC thus far consists of entirely rails.
Rails does it's validation 100% in the Model.
For the most part this works very well. I'd say 9 out of 10 times it's all you need.
There are some areas however where what you're submitting from a form doesn't match up with your model properly. There may be some additional filtering/rearranging or so on.
The best way to solve these situations I've found is to create faux-model objects, which basically act like Model objects but map 1-to-1 with the form data. These faux-model objects don't actually save anything, they're just a bucket for the data with validations attached.
An example of such a thing (in rails) is ActiveForm
Once the data gets into those (and is valid) it's usually a pretty simple step to transfer it directly across to your actual models.
The basic syntax check should be in the control as it translates the user input for the model. The model needs to do the real data validation.