Can a domain service can be call from domain entity, through service interface.
For eg- :
employee.Fire() calling IEmployee firing service. I am calling through Interface not through concrete one.
Is that possible ?
Though you can do that without any complilation error, but I don't think it's a good idea to call domain service in a domain entity.
Normally if the action affects more than one entities, we will put the logic in the service method. So if the fire action affects only current employee, should encapsulate inside employee.Fire(). Else if affects multi employees, should put in service and application should invoke service.Fire() instead of employee.File()
Related
I am very new to domain driven design and having a hard time understanding one thing which I will ask towards the end of this post.
Following are the facts that I am aware of, about DDD.
External REST call to get data for performing domain/business logic should happen in application layer.
Factories are a part of domain layer and should be used for creating domain objects.
Now, I am trying to devise a REST micro service. The payload of the POST service that I am designing, let's call it SearchRequest, is something that I am considering a part of my domain. SearchResponse, which is the response of my micro service's REST api is again a part of the domain.
My first question is, should SearchRequest & SearchResponse be a part of my domain model?
Also, for preparing SearchResponse I need to make an external API call, the request payload to which is present in a third-party jar. I need to write a complex logic to prepare the request payload for external api using data from SearchRequest.
Should the request payload for external API be a part of the domain? If yes, then I can have a factory in the domain layer to prepare the request payload. If not, then in which layer should I have the logic to create the same. Can I use factory in the application layer for creating objects that are not a part of the domain.
My first question is, should SearchRequest & SearchResponse be a part of my domain model?
Ideally, no. Request and response are application layer constructs. Application layer is meant to serve various use cases of a domain; it is not the domain itself.
Should the request payload for external API be a part of the domain? If yes, then I can have a factory in the domain layer to prepare the request payload.
Firstly, the external API payload is not part of your domain; it belongs to a different bounded context, expressed in its own ubiquitous language. A little background before coming to the exact potential solution: Two bounded contexts must not mingle freely for the obvious reason that the same concept may have different meanings in different bounded contexts. Communication between two domains must happen through an anti-corruption layer (ACL) that maps the external bounded contexts into your own and vice versa.
As Vaughn Vernon suggests in his book, the ACL may be implemented either as a domain service or even a repository, both belonging to the domain layer. Assuming you go with the domain service, pass the necessary fields from SearchRequest to a domain service method that makes the external call. The method hides the external service request construction logic and also the external service response mapping to your domain objects. The domain service contains references to objects (in your case the types defined in your third-party JAR) necessary to construct the external request but its clients remain ignorant about the external service's domain (bounded context).
The main rule here, that the domain model must not depend on anything. If it depends on something, then you must decouple it with interfaces or events.
I think the answer depends on how much these external API calls creep into your domain model.
a.) If it is just one call, then you can define an infrastructure service interface for the external API call and inject the infrastructure service into a domain service and call that domain service from your domain.
b.) If you use several different calls, then you can have multiple domain services and multiple infrastructure services.
c.) If you go real complex, then you can define repositories, entities, etc. too, maybe even a separate bounded context and end up with a complete anti corruption layer.
Suppose I am writing software for an insurance company. I use DDD and have a bounded context with entities related to the customer account, address, and related information. If a customer logs in and makes changes to these entities it is straightforward.
But as it is, there is another portal, which the internal support staff uses. Now if a customer calls in to update their account information (not a policy but phone number, address etc.). What is the best and clean way to do it?
Make a call to bounded context used by the customers (HTTP etc).
Allow making changes from the internal portal (probably modifying data across the database/schema boundaries).
Raise a domain event about changed object, and handle it on the customer side application (again this is an event related to a domain object in another context and we are not writing to database from the internal portal).
Bounded Contexts exist because they have a meaning in the domain and a reason to exist in your system. They don't exist to serve a specific type of user or a specific client application. In fact, it's most common that a Bounded Context serves multiple types of users and multiple client applications, especially in software systems with a customer-facing application and a back-office.
In your Insurance domain, both the customer and back-office users will directly interact with the CustomerManagement BC as this BC is there to serve both, not only the Customer. The same way that both the customers and back-office users will be able to see the customer's policies, their coverage, etc.
Technically, the implementation will depend on your architecture. Both client applications could talk to the same API and even share endpoints. Or you could provide an API per client, and these APIs would directly talk to the same BC (either calling the same code or by making remote calls to the same remote service).
You already answered your questions if your business allows user to directly change info about customers directly by phone call this is the case your system should allow to do it. This is what about DDD to focus on the domain and domain is business logic from your example I see the context customers management and some other contexts that use this info but if some one requires to change info about customers this is the business case and system should allow to do it!
currently I develop a backend based on the microservice architecture.
Unfortunately, I have a problem how to realize the authorization.
So let me explaine my system - there are the following services:
OAuth 2.0 Service (issuing JWT)
Group Service
Some Ressource Services (e.g. ToDos Service)
Every user is in one or many groups.
Each resource (like a ToDo list) also belongs to a group.
That means if some user creates a todo list, that list gets stored in the name of the group.
Szenario:
User A is in group A
User B is in group A and B
User C is in group C
User A creats a ToDo list in group A.
User B modifies this ToDo list (he is allowed to do this since he is also in group A)
User C also tries to modify this ToDo list, but he shouldn't allowed to do this since he is only in group C.
Has any body a great idea how I could realize this in a microservice architecture and keep the dependencies between the services on a minimum?
Certainly, I could ask on every request the Group Service if the user is in the group to which the resource belongs to. But so I get a really hard dependency between the Resource Services and the existence of a Group Service - I like to avoid this dependency.
Another option would be to store all groups, to which the user belongs to, in the access token. But with this option the client has to ask every time the OAuth Service for a new token when the user gets a member of a new group.
So is there any other option how I could realize this szenario?
So, you have three domains:
Authentication: responsible for identifying the user
Authorization: responsible for restricting access to resources
Todos: your core domain
You have done well identifying three bounded contexts, one for each domain and implemented in three microservices (MS). You are conforming to the best practices regarding DDD.
No, your question is how could you integrate those three microservices in such a way that the system is resilient, i.e. its microservices continue to work even if some of the other microservices fail.
You have two options regarding integration (communication between microservices):
Synchronous communication: every time the Todos MS receive a request, it queries the Authorization MS to check if the user is permitted to do what it wants. This has the advantage that is simple to implement but it has the disadvantage that is susceptible to cascade failure: if the Authorization MS fails then this MS also fails. So, this option is not good for you.
Asynchronous communication: somehow in the background, there is some data that is replicated from the Authorization MS to the Todos MS. You have at least two options for this replication to be done: a) in cron or scheduled tasks or similar and b) using a event driven architecture. This has the advantage that provides more resilience but it has the disadvantage that is more complex, harder to implement. This option seems to fit your need.
Further reading:
Building microservices
I would suggest to put the authorisation handling into a API gateway. When there is an incoming request the following steps are executed
1.The API gateway hits the OAuth server to get a transparent token which contains the access roles and groups of the user
2.The API gateway then calls the to do services with the access token , which the to do services use to decide if a particular user is authorised.
The advantage of this integration pattern is that the individual services don’t have to call the group service to get the roles.
According to my requirement in Liferay, I have created custom fields for roles and assigned it to a user. My goal is to call the JSONWS API and get these custom fields using NodeJS. I am not able to decide which API I should call.
This Url is having APIs: http://www.liferay.com/api/jsonws
I will appreciate for any kind of help.
Regards
AFAIK there is no options to access the expando value via exposed webserveices.
Probably what you can do is that, create a custom portlet, add a dummy entity in the service builder and in that expose a method for web service. In that method call the role API and expando API , and return the result you want.
Custom Fields are called "Expando" in the API and are modeled like virtual tables. The functionality that's exposed through webservices is ExpandoColumn and ExpandoValue. Probably the best way to figure out the parameters to give is to look at the matching database tables. Careful: You should only ever read the database and not be tempted to write to it.
I hate giving the advice to go to the database, but this is probably the quickest - at least for my explanation :)
Finally, I got a genuine solution without hitting database directly. JSONWS is having api :
/portal.expandovalue/get-data
Which helped me to get attributes assigned to a particular role.
The above API needs 5 parameters to be passed.
companyId: whaterver the companyId assigned for your liferay.
className: It depends upon, we created attribute for role or user
com.liferay.portal.model.Role or com.liferay.portal.model.User
tableName: CUSTOM_FIELDS
columnName: It is the same name you given for attribute
classPK: It is nothing but your role or user ID for which you have created Attribute.
In case you are getting "java.lang.NullPointerException" when using #user3771220 solution, try com.liferay.portal.kernel.model.User
I'm planning to write a service of event handling (like Google's Doodle) and, in the use case diagram, I need to distinguish between registered users and not registered users.
At first, I thought that:
Registered User _ is generalization of _ Not Registered User
with the following actions:
Not Registered User ---> Registration to the service
Not Registered User ---> Partecipate to an event
Registered User ---> Login to the service
But I don't know if I didn't understand the theory behind use cases:
should I use only one actor ("User") and associate him all the actions,
or keep this generalization?
Actor can be seen as the ROLE a user plays in a system. From this statement it is already clear that the single actor ("User") version does not model your situation correctly.
Generalization between two actors gives the specialized actor access to all the use cases associated with his parent-actor. In your case I would not say that this is the case. Maybe they even have some common use cases, but they both have use cases that do not make sense for the other one. For example:
Not registered user cannot login.
Registered user cannot registrate
They roles in the system are simply very different and therefore a generalization is not the perfect solution eihter.
I would simply make 2 separate actors, that eventualy share some use cases. I will assume that Not registered user can also participate in an event (maybe restricted), just to show that they can share some use cases, without the need to use generalization:
I would say that registered and unregistered user are states of user. Actor is a behaviored classifier and can have states. I think that there is only actor named "User". Use constraints to associations connected to user and usecase to restrict user participating on individual usecase. See example below: