Lets say I have an order which got updated on the UI with some values (they could be ok/not ok to ensure save)
1. How do we validate the changes made? Should the DTO which carries the order back to service layer be validated for completeness?
Once the validation is complete? How does the service return the validation errors? Do we compose a ReponseDTO object and return it like
ResponseDTO saveOrder(OrderDTO);
How do we update the domain entity order? Should the DTO Assembler take care of updating the order entity with the latest changes?
If we imagine a typical tiered' approach, ASP .NET on Web Server, WCF on Application Server.
When the Order form is updated with data on the web and saved. The WCF receives a OrderDTO.
Now how do we update the order from DTO? Do we use an assembler to update the domain object with changes from DTO? something like
class OrderDTOAssembler {
updateDomainObject(Order, OrderDTO)
}
I will try answer some of your questions from my experience and how I should approach your problem.
First I should not let DTO conduct any validations, but just plain POCO DTO's usually have different properties with specific datatypes, so some kind of validation is done. I mean you have to apply an integer street number and string for street name etc.
Second as you point out. Let a ORderDTOAssembler convert from OrderDTO to Order and vice versa. This is done in the application layer.
Third I would use Visitor pattern Validation in a Domain Driven Design like the example. The OrderService will use an IOrderRepository to save/update the order. But using the visitor-validation approach the OrderService vill call Order.ValidatePersistance (see link in example - but this is a extension method that is implemented in infrastructure layer since it has "db knowledge") to check its state is valid. If true, then we to IOrderRepository.Save(order).
at last, if Order.ValidatePersistance fails we get one or more BrokenRules messages. These should be returned to client in a ResponseDTO. Then cient can act on messages and take action. Problem here can be that you will have a ResponseOrderDTO messages but maybe (just came up with this now) all your ResponseDTO can inherit from ResponseBaseDTO class that expose necessary properties for delivering BrokenRule messages.
I hope you find my thoughts useful and good luck.
Related
A little background of my problem. I have a set of the following services:
AdapterService - intended for loading certain products from an external system
ApiGateway - accepts requests from UI. In particular, now there is only one request that receives product data to display product in UI from Product Service
ProductService - data storage service for various products. The service itself does not specifically know what kind of product it specifically stores. All types of products are created dynamically by other services that are responsible for these products. Product data is stored as a key-value map (technically it is a json string in DB column)
There is a schema for service interations
So, services in BLUE zone are mine (they can be changed in any way). RED zone describes services of another team (they can't be changed).
Whats the problem
To load product from external system I want to use SpecialProductDto which will store product data. I can use some validation features like Spring annotations and so on. Then to load the product from Adapter Service to ProductService I must transform SpecialProductDto to Map<String, Object> because ProductSerivcie requires it via API.
When I would get product info for UI through ApiGateway, I will need to call ProductService api for getting product that return attribues in Map<String, Object> and then transform this data to some UIReponse which contains some part of product data (because I dont need all product information, just only name and price for example).
But I also want to use SpecialProductDto in my ApiGateway service, because it seems working with Map<String, Object> is error prone... I practically need to fetch data blindly from Map to construct UIResponse. And what if some attribute names will be changed? With Map I only will know it when the request would be made from UI but using special DTO I get such exception in compilation time.
Question
So, what is the best practiсe or maybe patterт should I use in such situation? At the moment I see the following solutions:
Duplicate DTOs in both AdapterService and ApiGateway services. So, any changes in one class must be supported in another
Use Map<String, Object> at my own peril and risk, hoping that nothing will change there
Share SpecialProductDTO between ApiGateway and AdapterSerivce in some separate library and service (seems to be antipattern because of sharing someting can make a lot of problems)
Сan anyone help?
In my opinion, there's nothing wrong on duplicating DTOs.
Also, there's nothing wrong on providing the DTO in a separate library to be imported on each project, you will only be sharing the ProductService's contract and that's it. It does not cause any tight coupling between the Api Gateway and the Adapter. If the contract changes, then it must be changed on all of it's consumers (api gateway and adapter), simple as that.
About using Maps: usually I don't recommend this, because, like you said, you will not be able to take advantages of the built-in Bean Validations that Spring (and other frameworks) provides, but not only that, you'll also, depending on the situation, be using lots of casts and type conversions, which is not good and can be prevented by using DTOs.
Also, be aware that a DTO, in my opinion, should not be named with the suffix of 'DTO'. That's because a name like SpecialProductDTO doesn't clearly states where this object is being used or should be used.
Instead, prefer a something like CreateSpecialProductRequest - this indicates that this object is used when creating a Special Product. Another example is CreateSpecialProductResponse which just represents the response (if needed) after a Special Product creation. Take a look at this StackOverflow answer: Java data transfer object naming convention?
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 was wondering where exactly we should put input validations(imagine an API call send input to apply free times of a user). Is it right to inject validation class in service Layer and call validate method inside service? or it's better to put it in the infrastructure layer or even in Domain model? I just wanted to see a sample code that's implement validation of input for an API in Domain-driven design approach? what if I use CQRS architecture?
I use in my DDD/CQRS project following approach, structure of a project is API layer, Domain layer, Data Access layer, all input data from UI or from User are validated before, command are created and dispatched, to update the state of Domain, and we validate input data two times one is on the UI, (Angular app), and second one in Web API layer, if the data are valid the CQRS command are created and dispatched after that you can have Business logic validation. For validation you can use FastValidator or FluentValidation
UPDATE: Here is the simple example we have API for Create Batch Entity.
[HttpPost]
[Route("create")]
public IHttpActionResult Create([FromBody] BatchEditModel model)
{
var createCommand = model.Map<BatchEditModel, CreateBatchCommand>();
var result = (OperationResult<int>) _commandDispatcher.Dispatch(createCommand);
return Result(result);
}
As you can see as user input data will be BatchEditModel.
so we have BatchEditModelValidator which contains input data validation:
public class BatchEditModelValidator : AbstractValidator<BatchEditModel>
{
public BatchEditModelValidator()
{
RuleFor(x => x.Number).NotEmpty()
.WithMessage(ValidatorMessages.MustBeSpecified);
RuleFor(x => x.ClientId).GreaterThan(0)
.WithMessage(ValidatorMessages.MustBeSpecified);
RuleFor(x => x.EntryAssigneeId).GreaterThan(0)
.WithMessage(ValidatorMessages.MustBeSpecified);
RuleFor(x => x.ReviewAssigneeId).GreaterThan(0)
.WithMessage(ValidatorMessages.MustBeSpecified);
RuleFor(x => x.Description).NotEmpty()
.WithMessage(ValidatorMessages.MustBeSpecified);
}
}
this Validator will be executed before BatchEditModel will be mapped to CreateBatchCommand
and in CreateBatchCommandHandler we have Business logic validation CheckUniqueNumber
public OperationResult Handle(CreateBatchCommand command)
{
var result = new OperationResult<int>();
if (CheckUniqueNumber(result, command.ClientId, command.Number))
{
if (result.IsValid)
{
var batch = _batchFactory.Create(command);
_batchRepository.Add(batch);
_batchRepository.Save();
result.Value = batch.Id;
}
}
return result;
}
My approach is putting validation in the domain model, I validate the functionality of aggregates, entities, value objects, etc.
Then you can validate application services too, and user interface too. But those validations are a plus, a validation enhancement from the user point of view, as validation is faster.
Why this duplication of validations at different layers? Well, because if you just rely on UI or application service validations, it maybe possible that if they don't work well for whatever reason, and you don't validate the domain model, you are executing domain functionality without validating it.
Also, I would point out that not all the validations can be done at UI or at application layer, because you may have to access domain.
Finally, doing CQRS or not is independent on where you decide to put the validations. It's just that if you do CQRS, then validations at application layer are easier to do, as you can put them in decorators that wrap commands and queries.
Hope my explanation helps.
where should put input validation [in Domain Driven Design]?
This is largely unrelated to DDD, but: the closest possible to the input source.
You aren't going to wait until invalid data has crossed 4 layers to discard it.
Input validation precisely means you don't need anything else (e.g. loading other data) to check it, so you might as well do it as soon as you can. Of course, caveats apply, like any validation that can be circumvented must be double checked - client side javascript for instance.
what if I use CQRS architecture?
I wouldn't expect CQRS to change things very much.
Usually, by the time you are invoking a method in a domain entity, your inputs should have already been converted from their domain agnostic form into value objects.
Value objects are expected to be constructed in a valid state, and often include a check of a constraint within the constructor/factory method that produces it. However, in Java and similar languages, the implementation of the constructor usually throws (because constructors don't have any other way of reporting a problem).
Often what clients want instead is a clear understanding of all of the constraints violated by the input data, rather than just the first one. So you may need to pull the constraints out as first class citizens in the model, as predicates that can be checked.
You should validate in your app service before attempting to modify your domain. Validation should be towards the edges of your app (but not in the UI) so invalid or incomplete requests aren't even getting into your domain model.
I consider it two levels of validation because you will validate the request before attempting some behavior on the model then the model should again verify for internal consistency, since it can never be persisted in an invalid state.
It's a code design question :)
I have a DelegatingHandler which takes the http request header and validates the API-key. Pretty common task I guess. In my controller I call my business logic and pass along all business-relevant information. However now I'm challenged with the task to change behavior inside my business logic (separate assemblies) depending on certain api-keys.
Various possible solutions come to my mind...
Change business logic method signatures to ask for an api-key, too.
public void SomeUseCase(Entity1 e1, Entity2 e2, string apiKey);
Use HttpContext.Current to access the current request context. However I read somewhere that using HttpContext restrict my hosting options to IIS. Is there any better suited option for that?
var request = HttpContext.Current.Request; // next extract header information
Use Sessions (don't really want to go that road...)
What's your opinion on that topic?
I'd go for #1 although I don't like the idea of mixing in enivonmental stuff in business logic methods. But depending on your point of view you might argue the api-key is in fact logic-relevant.
Update #1:
I'm using a delegatingHandler to validate the apiKey and once it is validated I add it to the Request's Properties Collection.
The part in question is how the "api-key" or RegisteredIdentifier is passed along to the business logic layer. Right now I am passing the object (e.g. IRegisteredIdentifier) as a parameter to the business logic classes' constructors. I understand there is no more elegant way to solve this(?). I thought about changing the method signatures but I'm not sure whether it's interface pollution or not. Some methods need to work with the api-key, most don't. Experience tells me that the number will more likely grow than drop :) So keeping a reference to it in my bl classes seems to be a good choice.
Thank you for your answers - I think all of them are part of my solution. I'm new to StackOverflow.. but as far as I can see - I cannot rate answers yet. Rest assured I'm still thankful :)
I would suggest two different options.
Promote the value into a custom HTTP header (e.g. something like mycompany-api-key: XXXX ). This makes your delegating handler work more like a standard HTTP intermediary. This would be handy if you ever hand off your request to some secondary internal server.
Put the api-key into the request.Properties dictionary. The idea of the the Properties dictionary is to provide a place to put custom meta information about the request.
HTTP works hard to make sure authentication/authorization is a orthogonal concern to the actual request, which is why I would try and keep it out of the action signature.
I would go for option 1.
But you could introduce the entity RegisteredIdentifier (Enterprise Patterns and MDA by Jim Arlow and Ila Neustadt) in your business logic.
The api-key can be converted to a RegisteredIdentifier.
RegisteredIdentifier id = new RegisteredIdentitief(api-key);
public void SomeUseCase(Entity1 e1, Entity2 e2, RegisteredIdentifier id);
The business logic layer has a dependency on the API key. So I would suggest:
interface IApiKeyProvider
{
string ApiGet { get; }
}
..then have your BLL require that an object implementing that interface is supplied to it (in constructor, setup, or even each method that requires it).
Since in the future it might not be one API key. The key point is that this identifies the BLL is dependent on something, and defining a contract for the something.
Real-world example:
Then, in your DI container (Ninject etc), bind your own ConfigFileApiKeyProvider (or whatever) implementation to that interface, in the "place" (layer) that DOES have the API key. So the app that calls the BLL specifies/configures how the API key is specified.
Edit: I misunderstood the part about this being a "how-to-do-it-over-HTTP" question and not a code architecture/code design question. So:
HTTP header is the way to go in terms of transport
I'm slightly confused about what exactly the Model is limited to. I understand that it works with data from a database and such. Can it be used for anything else though? Take for example an authentication system that sends out an activation email to a user when they register. Where would be the most suitable place to put the code for the email? Would a model be appropriate... or is it better put in a view, controller, etc?
Think of it like this. You're designing your application, and you know according to the roadmap that version 1 will have nothing but a text based command line interface. version 2 will have a web based interface, and version 3 will use some kind of gui api, such as the windows api, or cocoa, or some kind of cross platform toolkit. It doesn't matter.
The program will probably have to go across to different platforms too, so they will have different email subsystems they will need to work with.
The model is the portion of the program that does not change across these different versions. It forms the logical core that does the actual work of whatever special thing that the program does.
You can think of the controller as a message translator. it has interfaces on two sides, one faces towards the model, and one faces towards the view. When you make your different versions, the main activity will be rewriting the view, and altering one side of the controller to interface with the view.
You can put other platform/version specific things into the controller as well.
In essense, the job of the controller is to help you decouple the domain logic that's in the model, from whatever platform specific junk you dump into the view, or in other modules.
So to figure out whether something goes in the model or not, ask yourself the question "If I had to rewrite this application to work on platform X, would I have to rewrite that part?" If the answer is yes, keep it out of the model. If the answer is no, it may go into the model, if it's part of the essential logic of the program.
This answer might not be orthodox, but it's the only way I've ever found to think of the MVC paradigm that doesn't make my brain melt out of my ear from the meaningless theoretical mumbo jumbo that discussions about MVC are so full of.
Great question. I've asked this same question many times in my early MVC days. It's a difficult question to answer succintly, but I'll do my best.
The model does generally represent the "data" of your application. This does not limit you to a database however. Your data could be an XML file, a web resource, or many other things. The model is what encapsulates and provides access to this data. In an OOP language, this is typically represented as an object, or a collection of objects.
I'll use the following simple example throughout this answer, I will refer to this type of object as an Entity:
<?php
class Person
{
protected $_id;
protected $_firstName;
protected $_lastName;
protected $_phoneNumber;
}
In the simplest of applications, say a phone book application, this Entity would represent a Person in the phone book. Your View/Controller (VC) code would use this Entity, and collections of these Entities to represent entries in your phone book. You may be wondering, "OK. So, how do I go about creating/populating these Entities?". A common MVC newbie mistake is to simply start writing data access logic directly in their controller methods to create, read, update, and delete (CRUD) these. This is rarely a good idea. The CRUD responsibilities for these Entities should reside in your Model. I must stress though: the Model is not just a representation of your data. All of the CRUD duties are part of your Model layer.
Data Access Logic
Two of the simpler patterns used to handle the CRUD are Table Data Gateway and Row Data Gateway. One common practice, which is generally "not a good idea", is to simply have your Entity objects extend your TDG or RDG directly. In simple cases, this works fine, but it bloats your Entities with unnecessary code that has nothing to do with the business logic of your application.
Another pattern, Active Record, puts all of this data access logic in the Entity by design. This is very convenient, and can help immensely with rapid development. This pattern is used extensively in Ruby on Rails.
My personal pattern of choice, and the most complex, is the Data Mapper. This provides a strict separation of data access logic and Entities. This makes for lean business-logic exclusive Entities. It's common for a Data Mapper implementation to use a TDG,RDG, or even Active Record pattern to provide the data access logic for the mapper object. It's a very good idea to implement an Identity Map to be used by your Data Mapper, to reduce the number of queries you are doing to your storage medium.
Domain Model
The Domain Model is an object model of your domain that incorporates behavior and data. In our simple phone book application this would be a very boring single Person class. We might need to add more objects to our domain though, such as Employer or Address Entities. These would become part of the Domain Model.
The Domain Model is perfect for pairing with the Data Mapper pattern. Your Controllers would simply use the Mapper(s) to CRUD the Entities needed by the View. This keeps your Controllers, Views, and Entities completely agnostic to the storage medium. This also allows for differing Mappers for the same Entity. For example, you could have a Person_Db_Mapper object and a Person_Xml_Mapper object; the Person_Db_Mapper would use your local DB as a data source to build Entities, and Person_Xml_Mapper could use an XML file that someone uploaded, or that you fetched with a remote SOAP/XML-RPC call.
Service Layer
The Service Layer pattern defines an application's boundary with a layer of services that establishes a set of available operations and coordinates the application's response in each operation. I think of it as an API to my Domain Model.
When using the Service Layer pattern, you're encapsulating the data access pattern (Active Record, TDG, RDG, Data Mapper) and the Domain Model into a convenient single access point. This Service Layer is used directly by your Controllers, and if well-implemented provides a convenient place to hook in other API interfaces such as XML-RPC/SOAP.
The Service Layer is also the appropriate place to put application logic. If you're wondering what the difference between application and business logic is, I will explain.
Business logic is your domain logic, the logic and behaviors required by your Domain Model to appropriately represent the domain. Here are some business logic examples:
Every Person must have an Address
No Person can have a phone number longer than 10 digits
When deleting a Person their Address should be deleted
Application logic is the logic that doesn't fit inside your Domain. It's typically things your application requires that don't make sense to put in the business logic. Some examples:
When a Person is deleted email the system administrator
Only show a maximum of 5 Persons per page
It doesn't make sense to add the logic to send email to our Domain Model. We'd end up coupling our Domain Model to whatever mailing class we're using. Nor would we want to limit our Data Mapper to fetch only 5 records at a time. Having this logic in the Service Layer allows our potentially different APIs to have their own logic. e.g. Web may only fetch 5, but XML-RPC may fetch 100.
In closing, a Service ayer is not always needed, and can be overkill for simple cases. Application logic would typically be put directly in your Controller or, less desirably, In your Domain Model (ew).
Resources
Every serious developer should have these books in his library:
Design Patterns: Elements of Reusable Object-Oriented Software
Patterns of Enterprise Application Architecture
Domain-Driven Design: Tackling Complexity in the Heart of Software
The model is how you represent the data of the application. It is the state of the application, the data which would influence the output (edit: visual presentation) of the application, and variables that can be tweaked by the controller.
To answer your question specifically
The content of the email, the person to send the email to are the model.
The code that sends the email (and verify the email/registration in the first place) and determine the content of the email is in the controller. The controller could also generate the content of the email - perhaps you have an email template in the model, and the controller could replace placeholder with the correct values from its processing.
The view is basically "An authentication email has been sent to your account" or "Your email address is not valid". So the controller looks at the model and determine the output for the view.
Think of it like this
The model is the domain-specific representation of the data on which the application operates.
The Controller processes and responds to events (typically user actions) and may invoke changes on the model.
So, I would say you want to put the code for the e-mail in the controller.
MVC is typically meant for UI design. I think, in your case a simple Observer pattern would be ideal. Your model could notify a listener registerd with it that a user has been registered. This listener would then send out the email.
The model is the representation of your data-storage backend. This can be a database, a file-system, webservices, ...
Typically the model performs translation of the relational structures of your database to the object-oriented structure of your application.
In the example above: You would have a controller with a register action. The model holds the information the user enters during the registration process and takes care that the data is correctly saved in the data backend.
The activation email should be send as a result of a successful save operation by the controller.
Pseudo Code:
public class RegisterModel {
private String username;
private String email;
// ...
}
public class RegisterAction extends ApplicationController {
public void register(UserData data) {
// fill the model
RegisterModel model = new RegisterModel();
model.setUsername(data.getUsername());
// fill properties ...
// save the model - a DAO approach would be better
boolean result = model.save();
if(result)
sendActivationEmail(data);
}
}
More info to the MVC concept can be found here:
It should be noted that MVC is not a design pattern that fits well for every kind of application. In your case, sending the email is an operation that simply has no perfect place in the MVC pattern. If you are using a framework that forces you to use MVC, put it into the controller, as other people have said.