Unfortunately, I am not sure what your first question really means, therefore am unable to answer that, but I can help you with the rest.
2) We're currently performing validation on the request data before
passing it into our immutable command objects. However, there may be
some cases where we need parse data from the DB/CLI prior to
initializing our commands.
As a result, I've considered placing our validation logic into the
command objects themselves. If validation fails then a exception might
be thrown. Does this seem like a reasonable approach or am I again
violating some design principles?
What you should ask yourself is why are you dealing with invalid objects in the first place so that they require validation after they are created?
There are two situations why this could happen:
- you do not trust the variables which are used when an object is created
- you do not trust the objects themselves, you do not believe, that what they are doing with their data is perfect
Both of these cases are bad, but the second one is much worse.
The first case can and does happen, when you use variables, which the user has control over. Ie. he can input anything he want. This is something you really have no control over, so you need to make sure to check all options before creating an object.
The second case happens when, even though you model a class, you do not trust the class does what it is supposed to do. Do you perhaps expose too much of its internal structure, giving the programmer too many posibilities on how to operate on the object, perhaps having simple getters and setters, instead of actual methods?
I said the second case is worse. The reason why it is worse is because you do not trust your own domain. And if you cannot trust it, then who?
3) This may sound foolish but what exactly is the difference between a
Domain Object and a DTO. I've heard the command objects themselves
being referred to as a DTO yet they appear to belong to the domain
layer (unless I'm mistaken).
DTO is a very simple and stupid object which consists only from getters and setters and glues small chunks of seemingly related information together to make one larger structure, so the data requests may be reduced.
Martin Fowler provides a simple example of a DTO object.
Domain model is an object containing your business logic. It is an object which should have no methods starting with the prefix set
, it should follow the Tell, Don't ask principle, etc. The domain is the core of your application, the domain objects make sure, everything works well, they throw domain exceptions on invalid operations to make sure, they are always in a valid state.
The Tell, Don't ask principle provides encapsulation. It turns this:
if (personObject.GetSex() == "Male") { ... }
into this:
if (personObject.IsMale()) { ... }
The programmer using a Person
class no longer cares, how the Sex
property is represented, if it is a string
, an enum
or a boolean
. The only thing it cares about is the Person::IsMale : boolean
method.
Domain model summary: It is an object containing data which are directly tied to it (no persistence logic is allowed, the object has to deal only with its own data) and encapsulates operations to make sure once created, it will never find itself in an invalid state.
Best Answer
There is no need for writing
try-catch
-Blocks all over the controller.1) I would derive those Exceptions from a common ancestor
2) There is ExceptionHandler which catches exceptions of a certain kind and gives control to you, what to do next. In the exception, you could carry a message, which is returned, via the reponse's body.
Regarding to security concerns or leaky abstractions, I see no problem in providing in the response's body a reason like
missing required field "password"
orCould not publish. Document is already published
.Of ocurse you should avoid turning things inside out.