I'm looking at developing a system (primarily web based) that has a clearly defined domain.
Parts of the domain include entities like Diary, Booking, Customer, etc.
However I created another entity called User whose intention is for authentication and authorization only (it seemed wrong to contaminate the Customer entity with data specific to authentication). I figure this isn't part of the domain of "making bookings", but specifically this should belong to the application layer (I'm trialling a hexagonal architecture).
I'm accessing my repositories using interfaces in my domain model and wiring them up to my persistence layer using IoC.
My questions are this:
Should I put the authentication/authorization code in the application
and keep it out of the domain?
If I do keep it out of the domain, should I put the interface for the
UserRepository in the application layer also (I think this would
make sense)?
If I do keep it out of the domain, I will end up with entities also in the application layer called User etc. This seems wrong.
What are people's thoughts?
[EDIT]
I've gone for a solution that takes a bit from both answers, so thanks for answering and I've +1'd you both.
What I've done is put the authentication/authorisation code in a subdomain (secondary adapter), in a separate project, and because it requires access to it's own persistence (a few collections in a separate RavenDB database), I'm including these straight into the separate project keeping them separate from the main persistence layer.
Should I put the authentication/authorization code in the application
and keep it out of the domain?
No, you should keep authentication/authorization code out of the core domain. It belongs to a generic subdomain.
If I do keep it out of the domain, should I put the interface for the
UserRepository in the application layer also (I think this would make
sense)?
You could keep UserRepository in the domain layer, but you'd better keep the "access and identify" subdomain and the "making bookings" core domain separated with each other. You could use different packages or namespace.
The next challenge is how to integrate these two domains. In my humble opinion, you may:
Expose a DomainService from "access and identify" subdomain to the application layer for making authentication/authorization decisions.
Sometimes we have to find out who made Diaries and Bookings, in this case, use the identifier of the User is enough. Other information such as "favorite tags" or something like that is usually not needed in "making booking" core domain.
Authentication is a generic domain, not a part of your domain. So, yes, keep it in some component in application layer.
Not all parts of your system should follow DDD patterns. You can use UserRepository if you see a benefit for this but I would use just some already available component/popular library of your environment like MembershipProvider in ASP.NET world.
Related
I am new to DDD and this is the first project for me to apply DDD and clean architecture,
I have implemented some code in the domain layer and in the application layer but currently, I have a confusion
now I have an API which is placeOrder
and to place the order I need to grab data from other microservices, so I need to grab production details from product service and address details from user profile microservice
my question is, should these data are pulled into the domain layer or in the application layer?
is it possible to implement a domain service that has some interfaces that represent the product service API and use that interface in the domain layer and it will be injected later using dependency injection or should I implement the calling of this remote API in the application layer?
please note that, calling product service and address service are prior steps to create the order
Design is what we do when we want to get more of what we want than we would get by just doing it. -- Ruth Malan
should these data are pulled into the domain layer or in the application layer?
Eric Evans, introducing chapter four of the original DDD book, wrote
We need to decouple the domain objects from other functions of the system, so we can avoid confusing the domain concepts with other concepts related only to software technology or losing sight of the domain altogether in the mass of the system.
The domain model doesn't particularly care whether the information it is processing comes from a remote microservice or a cache. It certainly isn't interested in things like network failures and re-try strategies.
Thus, in an idealized system, the domain model would only be concerned with the manipulation of business information, and all of the "plumbing" would be somewhere else.
Sometimes, we run into business processes where (a) some information is relatively "expensive" to acquire and (b) you don't know whether or not you need that information until you start processing the work.
In that situation, you need to start making some choices: does the domain code return a signal to the application code to announce that it needs more information, or do we instead pass to the domain code the capability to get the information for itself?
Offering the retrieve capability to the domain code, behind the facade of a "domain service" is a common implementation of the latter approach. It works fine when your failure modes are trivial (queries never fail; or abort-on-failure is an acceptable policy).
You are certainly going to be passing an implementation of that domain service to the domain model; whether you pass it as a method argument or as a constructor argument really depends on the overall design. I wouldn't normally expect to see a domain entity with a domain service property, but a "use case" that manipulates entities might have one.
That all said, do keep in mind that nobody is handing out prizes for separating domain and application code in your designs. "Doing it according to the book" is only a win if that helps us to be more cost effective in delivering solutions with business value.
I've read a lot about microservices, but one question remain : the security.
What I would like to do is something similar to Netflix, i.e one general backend and many backends for each front end (for example mobile devices, desktop app, ...).
On the top of that I plan to put my firewall security layer. Here is the problem : how to authorize a request through this layer only once and not in each microservice ?
Is is possible to expose certain microservices to the whole internet, and others only to trusted sources ? If so, is it the right way ?
You've read a lot, but not too much. Please give a look at:
Building microservices (it talks about every aspect of MSs, and also about security)
The Practice of Cloud System Administration (not strictly MS relatad but containts many useful information)
One solution would be assigning a public IP to the microservice you want to expose, and then perhaps have a VPN set-up that trusted entities use to access the other microservices.
Since the most similar questions are related to ASP MVC I want to know some common right choice strategies.
Lets try to decide, will it go into the business layer or sit on the service layer.
Considering service layer to have a classical remote facade interface it seems to be essential just to land permission checks here as the user object instance is always here (the service session is bound to the user) and ready for .hasPermission(...) calls. But that looks like a business logic leak.
In the different approach with an implementation of security checks in the business layer we pollute domain object interfaces with 'security token' arguments and similar things.
Any suggestions how to overcome this tradeoff or maybe you know the only true solution?
I think the answer to this question is complex and worth a bit of thought early on. Here are some guidelines.
The service layer is a good place for:
Is a page public or only open to registered users?
Does this page require a user of a specific role?
Authentication process including converting tokens to an internal representation of users.
Network checks such as IP and spam filters.
The business layer is a good place for:
Does this particular user have access to the requested record? For example, a user should have access to their profile but not someone else's profile.
Auditing of requests. The business layer is in the best situation to describe the specifics about requests because protocol and other details have been filtered out by this point. You can audit in terms of the business entities that you are setting policy on.
You can play around a bit separating the access decision from the enforcement point. For example, your business logic can have code to determine if a user can access a specific role and present that as a callback to the service layer. Sometimes this will make sense.
Some thoughts to keep in mind:
The more you can push security into a framework, the better. You are asking for a bug (and maybe a vulnerability) if you have dozens of service calls where each one needs to perform security checks in the beginning of the code. If you have a framework, use it.
Some security is best nearest the network. For example, if you wish to ban IP addresses that are spamming you, that definitely shouldn't be in the business layer. The nearer to the network connection you can get the better.
Duplicating security checks is not a problem (unless it's a performance problem). It is often the case that the earlier in the workflow that you can detect a security problem, the better the user experience. That said, you want to protect business operations as close to the implementation as possible to avoid back doors that bypass earlier security checks. This frequently leads to having early checks for the sake of UI but the definitive checks happening late in the business process.
Hope this helps.
I'm modeling my first DDD application and I caught stuck with this doubt...
In my application and infrastucture layers I have some details that need to be persisted, but, since these are not domain specific, I don't like to name it repositories. Someone can help me figure out how to name it?
Thanks.
DDD and the Repository pattern (RP) are different things, it just happens that DDD makes use of RP. This means that you can wrap everything related to persistence in repositories, they just won't be Domain Repositories. Probably in your case you'd have PaymentGatewaysRepository or smth like that.
Point is, if you wrap persistence access details into a class so that the rest of the app doesn't care about storage, you're using the repository pattern no matter how you'll name that class.
You should elaborate some more... Why isn't it modeled? Is it only configuration settings, things outside of the scope of the model? Like logs, etc? Some names come to mind: Serialization, configuration, settings, etc.
Considering your comment, configuration settings are really orthogonal to a Domain Model, but payment gateway settings may or may not be outside of the model. Id depends on the kind of application you are writing. I believe that if you are writing a payment processor, then it is a bona fide "member of your" domain model :-) You can also model generic configurations in the model... imagine that your users will have their own overriden settings.. The config "model" could weakly reference the domain model...
You can also model these specifics in another domain entirely... a reusable domain model with its own persistence, and which could be used in different domains as an add-on...
I'm working on my first "real" DDD application.
Currently my client does not have access to my domain layer and requests changes to the domain by issuing commands.
I then have a separate (flattened) read model for displaying information (like simple CQRS).
I'm now working on configuration, or specifically, settings that the user configures. Using a blog application as an example, the settings might be the blog title or logo.
I've developed a generic configuration builder that builds a strongly typed configuration object (e.g. BlogSettings) based on a simple key value pair collection. I'm stuck on whether these configuration objects are part of my domain. I need access to them from the client and server.
I'm considering creating a "Shared" library that contains these configuration objects. Is this the correct approach?
Finally where should the code to save such configuration settings live? An easy solution would be to put this code in my Domain.Persistence project, but then, if they are not part of the domain, should they really be there?
Thanks,
Ben
User configurable settings belong to domain if they are strongly typed and modeled based on ubiquitous language, i.e. 'BlogSettings'. The only difference between settings and other domain objects is that conceptually settings are 'domain singletons'. They don't have a life cycle like other Entities and you can only have one instance.
Generic configuration builder belongs to Persistence just like the code that is responsible for saving and reading settings.
Having found this question, I feel obliged to suggest an answer because I don't like the accepted one.
First off I don't see why this has to be a singleton.
Secondly, there is something about settings that is very important: they are usually hierarchical, and they almost always have to have the concept of defaults. Sometimes those defaults are at the item level. Other times you might prefer to replicate a whole set of defaults. Also, consider the fact that settings can use the concept of inheritance: maybe an agency has a setting, but it permits agents the ability to do their own.