The first issue I have with using exceptions for validation is that I would typically expect the outcome of the validation to potentially churn up multiple errors with the same data.
Exceptions are useful for non-Happy Path scenarios when some code fails and the best course of action is to unwind the stack as a consequence, passing the error much further ...
It seems to me that in your example the two exceptions are exceptional. ie. you don't expect them to be thrown very often.
The problem with the overall pattern is usually you DO expect validation checks to fail.
I would code this up the same way you have. But I would in addition have code which performed the same validation checks before submitting the ...
Your question effectively asks: when should I favour delegating responsibility for input validation to my methods?
It really depends. Looking through the details, it appears you are actually trying to solve a philosophical problem: when is interface simplicity more valuable than implementation simplicity?
If calling code is expected to handle input ...
Both can be useful, but neither is better.
Which way this is handled has to be determined by gathering data and making decisions. Making the decision is a complex process that depends on requirements, what assumptions are safe to make and how the functions will be used.
Start with your "A" case:
...Do expensive validity check, ...
Software verification and validation are all the activities that ensure that the software fulfils all the needs and requirements for its intended purpose. As such V&V is part of the larger set of Quality Assurance activities (the latter also include activities to improve the quality, beyond the area of quality control to which V&V belongs)
I'm going to go with "no" because not only does that mean more round-trips to the DB, but also you can't guarantee that another call to the same API isn't happening at the same time, so you can't be certain that the delete call isn't still being made against an already deleted record.
Instead, just try and do the delete and handle appropriately if the DB ...
At what stage in the whole process is the best time to implement these tests - when loading the data or when running the model on the data?
Instead, separate the process in 3 stages:
Running the model on the data
This makes validation independent from 1 and 3, which allows to reuse the validation also in other contexts. ...
It should be strongly avoided (for the reasons you mention), but is sometimes better than the alternatives. Where necessary, it's really common to make a (local) cache to mitigate the performance concerns and to decrease the failure concerns.
The relationship... doesn’t exist.
Modern software development generally doesn’t have discrete phases where you take and validate some input, do some work, and then pass it down the assembly line. And these days even having a separate role for testers or other quality assurance work is more and more rare.
At the scale necessary for most software, the ...
Server-side validation is for security, so users can't bypass client-side validation and send potentially harmful requests.
Client-side validation is for usability, so users can immediately see that for example certain fields are required or need a specific format.
They're not necessarily identical, although in many cases very similar. For example a ...
I used to do this with XML back in the day. The idea is that you give your clients a schema and you should guarantee that you follow it, otherwise you might cause an error.
I agree with you though, Unit testing seem a better way of doing this for 99% of cases. You can imagine a complicated schema an a service which builds up a response with info from other ...
What is your goal?
Writing a quirky programming language to validate input.
If your goal is to just validate the input, I would hard-code it. It is unlikely that your service running in production will suddenly gain an appreciation for a different request format. That would indeed be quite startling.
If your goal is to permit custom ...
Did the failure happen because of something wrong with the command or because of something wrong with the state of the system being commanded?
You can save anything you like. What determines what you should save is what you're going to do with it.
The typical use of an event store when doing event sourcing is to rebuild state by replaying the events. Much ...
I would advise against HTTP 400 for syntactically correct (here a 400 would be misleading), but semantically incorrect (aka invalid) request. But that should not be the topic here.
The question is more about validation and DRY.
I think, there is no golden rule to follow here. If you are doing a modern web application, there is a tradeoff between double ...
The controller should always handle validation. Because its the only one capable of actually presenting the problem to the user (be that a message, some sort of highlight, etc..).
That being said, always enforce invariants in the core model. I'm not talking about business rules, those should be enforced by business logic. I'm talking about structural rules. ...
The reason is simple. It is always possible for the caller (service) of the validation component (model) to issue a query for the appropriate data and pass it as a parameter instead of having the validation component (model) send the query itself.
public function validateData($database, $dataId)
$data = $database->getData($...
I agreed. I have the same feeling of rejection when it comes to calling external services. How @Telastyn say, some times is necessary so worth doing a bit of research to meet in deep the tools and the alternatives at hand.
@Telastyn also mentioned caches. In line with his argument, I suggest meeting your tools first because some of them implement cache out ...
There is a third option: don't return.
In your first example the client using your function is responsible
for being sure data is valid before passing it,
for dealing with the result of calling the function, and
for knowing when to call the function
In your second example the client is responsible
for dealing with the result and
for knowing when to ...
As you point out, the purpose of requring objects to always be in a consistent state is to avoid the need to re-validate the object's state outside the object whereever it is used - and thereby spreading the knowledge of what an e-mail address is all throughout the code base (DRY).
But this really just makes sense if you have an actual model that does ...
The events in your event stream should be representations of changes to the state of your domain model.
There's nothing "against the rules" with including failed operations in the state of your domain model.
Invalid Operation Attempted is lousy spelling, but a domain specific equivalent would be reasonable.
The only way I know you could solve is by find a trusted third party, hand your code over to them and let them compile and run it (maybe on a neutral cloud platform). If you want to provide / host the server on your own, you will probably have to let the trusted third party audit your internal processes.
No that is impossible. Even if you included a service method that has some challenge/response mechanism, the service provider could run a proxy and pass on the request. And any mechanism could be reproduced easily because it is all open.
Even knowing they are running the same sever would not guarantee it would behave as expected. Results could be input ...
One approach is
Application requests a license key at startup, attach either a random or hardware based id and the username to the request. The server finds the appropriate key and marks it as used, with the id and other relevant data. This can be done by using a separate 'used licenses' table or by updating the licese key row.
Application sends a keep ...
A method containing code to run just with specific external conditions can:
decide whether to execute after checking those conditions, or
just blindly run, sticking to the Single Responsibility Principle; and let the calling code check the conditions, deciding to call the method or not.
Generally this depends on the data needed to make the ...
The answer is, it depends. And it mainly depends on the scope of your function/method.
If the method is public and especially if it forms part of an API that will be called by other code, possibly written by other organisations, then it makes sense for the method to validate and verify its conditions.
If the method is internal or private, ie is an ...
The use for exceptions for this kind of validation is "bad" because, for the code as given, you actually do not want this kind of validation. You write:
public async Task<UserDto> RegisterNewUserAccount(CreateAccountDto userInfo)
What you have here is ...
In your particular example with context you provided:
- without examples of how controller endpoint is consumed
It could be ok to throw exceptions when some "exceptional" validations fails. As you mentioned that you will not use exception for non-exceptional validations (general user input)
I think name Ensure.. should be ok for method which will throw ...
The biggest practical problem you’ll encounter is performance difference. The cost of checking a return value versus stopping execution, unwinding the stack, and otherwise dealing with exceptions is about an order of magnitude.
“That’s not a big deal”, you say, “the call to the DB is way more expensive!”
And it is. The problem comes that if you’re at any ...
This is a question I have been asking myself and doing research for quite some time now.
Below are a couple of ways you could be telling the caller of your constructors/methods what went wrong during the process they requested, in order of how idiomatic they are (but in reverse order of how effective I consider them):
Throw a composite (domain) exception
Business validation (i.e. checking if the value follows the rules) should occur in the business layer (BLL), not the DAL where the repositories live.
Data validation (i.e. checking if the entered value is allowed by the database) happens on the data layer, but it is usually handled by the ORM itself and doesn't require explicit validation by you. You may ...