What is DDD's Aggregate in SpringBoot MVC? - spring-boot

Suppose I've a bunch of microservices, each written on SpringBoot MVC (REST, Controller, Service, etc..)
Can anybody explain what is DDD's Aggregate in SpringBoot MVC? is it a controller? Or is it a specific microservice which is a root for some other microservices?
In other words, is aggregate something within a service with a controller's endpoint as a root? or is aggregate a sub-set of microservices with a particular SpringBoot application/service as an entry point to them?

It is neither a controller nor specific microservice.
It is a cluster of the domain objects that can be treated as a single unit (e.g. Order and its order line) (see this) which is retrieved , saved and searched by the repository.
The spring framework also provides an more specialised #Component called #Repository to represent the repository concepts (quoted from its javadoc) :
Indicates that an annotated class is a "Repository", originally
defined by Domain-Driven Design (Evans, 2003) as "a mechanism for
encapsulating storage, retrieval, and search behavior which emulates a
collection of objects".
Teams implementing traditional Java EE
patterns such as "Data Access Object" may also apply this stereotype
to DAO classes, though care should be taken to understand the
distinction between Data Access Object and DDD-style repositories
before doing so. This annotation is a general-purpose stereotype and
individual teams may narrow their semantics and use as appropriate.
As we use repository to save JPA #Entity or MongoDB #Document to the underlying datastore , so DDD aggregate is more align to them

Two things here.
Spring MVC is a boundary layer to translate between HTTP and internals of the app. The internals are where all the DDD happens, not the boundary itself
Spring Boot is for bootstrapping an application with all the common tools and making a runnable deployment unit.
So, in case of DDD an HTTP request comes to Spring MVC layer, there a domain request is instantiated and passed to domain core for execution. Domain response then comes back and is translated into HTTP response by Spring MVC layer.

Related

Two approaches to implementing REST API on Spring

I do REST API on Spring. Took a course in Spring Data Hibernate and found that it made the REST API the most time-consuming way.
When I added a new entity to the domain, I went through the following chain of objects:
Entity - domain object
DTO - for transmitting/receiving an object to/from a client
Mapper - to convert between Entity and DTO
Repository - for interacting with the database
RestController - for processing API requests
Service - service class for the object
The approximate chain of my actions was as follows:
RestController processes requests - receives DTO from the client (in case of creation of a new object)
Mapper in controller converts DTO to Entity
Service is called
Service accesses the Repository
Repository returns the result of execution (created by Entity)
Service returns Entity is created in RestController
RestController returns to the client an object of type ResponseEntity, where I put the body and response code.
As you can see a large chain of actions and a large number of objects.
But then I found out that if you use Spring Data REST, all this doesn't need all the API supplied by Spring from the box. In general, you only need to create an Entity and Repository.
It turns out that for typical CRUD-type operations, I wrote a lot of controllers and their methods in vain.
Questions:
When should I use RestConroller, and when is Spring Data REST?
Is it possible to combine two approaches for one Entity? It turns out that I was wasting my time writing for simple operations like creating, getting, saving, deleting controllers, it can be moved to Spring Data REST.
Will I be able to implement some of the actions that I did in Spring Data Rest in RestConroller? Such as:
Return an entity property value as id instead of object? I mean I have properties for entities that are entities themselves, for these fields I sometimes need to return their ID instead of the whole entity.
Is there any way to control error handling? In RestController I have implemented the ResponseEntityExceptionHandler extension class and all errors wherever they occur in my RestController are handled in the same way in one place and I always know that all errors will return approximately the same response structure.
Data validation will have to be hinged on the fact that it used to be validated on DTOs received from the client. Are there any nuances waiting for me in this regard?
I'm a little stumped on how to move forward. Give me your recommendations and thoughts on this. Push forward on what to use and how.
What Spring Data REST can do for you is scaffolding of the plain repository to rest service. It is much faster, and in theory it should be flexible, but in practice it is hard to achieve something more than REST access to your repositories.
In production I've used Spring Data REST as a wrapper of the database - in a service/microservice architecture model you just wrap-up sometimes the core DB into such layer in order to achieve DB-agnostic Application. Then the services will apply the business logic on top of this wrapper and will provide API for the front-end.
On the other hand Spring Data Rest(SDR) is not suitable if you plan to use only these generated endpoints, because you need to customize the logic for fetching data and data manipulation into Repoitories/Services. You can combine both and use SDR for the "simple" entities, where you need only the basic CRUD over them, and for the complex entities to go with the standard approach, where you decouple the entity from the endopint and apply your custom business logic into the services. The downside of mixing up both strategies is that your app will be not consistent, and some "things" will happen out-of-the-box, which is very confusing for a new developer on this project.
It loooks wasted time and efforts to write these classes yourself, but it only because your app doesn' have a complex database and/or business logic yet.
In short - the "standard" way provides much bigger flexibility at the price of writing repetetive code in the beginning.
You have much more control building the full stack on your own, you are using DTO's instead of returning the entity objects, you can combine repositories in your services and you can put your business logic on the service layer. If you are not doing anything of the above (and you don't expect to in the near future) there is no need for writing all that boilerplate yet over again, and that's when Spring Data REST comes into play.
This is an interesting question.
Spring Data Rest provides abstraction and takes a most of the implementation in its hand. This is helpful for small applications where the business logic resides at the repository layer. I would choose this for applications with simple straight forward business logic.
However if I need fine grained control (eg: transaction, AOP, unit testing, complex business decisions etc. ) at each of the layers as you mentioned which is most often needed for large scale applications I will prefer writing each of these layers.
There is no thumb rule.

What is the purpose of utility layer and how is this linked with other layers in a web application architecture?

I am new to Java EE architecture (trying to do some reading on this - please suggest good sources).
When we use MVC pattern, the DAO layer consists of classes that contain methods to access the database. Similarly service layer contains classes that make use of methods from DAO classes and have some business logic. I see in some projects that Util classes are used and they contain methods that perform some work for the service layer classes.
What is the exact purpose of this Utility layer? Can it contain getters and setters from Spring dependency injection?
There is no "utility layer". Constructions like like MyMagnificentMailer are just a different kind of service. I am not sure if you actually separate the domain objects from DAOs (or other forms of abstraction for storage ), but just like domain object can contain and interact with other domain object, same way your Authentication service can interact with Mailer and vice versa.
There is not rule saying, that real services have to be build on top DAOs.

Regarding DDD Structure and Layering.

Folks,
Apologies if this has been covered in another thread, but I have searched ddd and mvc articles and have not found a straightforward answer.
I am hoping to apply a DDD approach to the architecture of my MVC projects. Please correct me where I am wrong.
All MVC controller actions that involve hitting the domain model will initially hit
and application service layer.
The application service layer here acts as a facade between presentation and the domain.
Any requests from the application service later that clearly involve discrete domain aggregates will perform fetch or modify operations on aggregate roots using repositories. Each aggregate root will have its own repository.
so the application service layer must be injected with any/all repositories required by the domain.
Where an operation may involve multiple aggregates or requires logic that does not fit neatly into one aggregate, the application service will call a domain service to carry out operations across aggregates.
This does not seem right to me.
My confusion is that from a DDD perspective Im not sure whether for example aggregate roots should perform their own persistance i.e. the aggregate gets injected with a repository and then persists/fetches itself or whether as above the application service layer uses repositories to act on or fetch aggregates?
Also if the application service layer is injected with all repositories, does the domain service that the application service layer calls also need repositories injected?
Im keeping CQRS out of this at this point. I want to get the layering and the relationship between services and aggregates sorted out first.
Thanks for any advice.
All MVC controller actions that involve hitting the domain model will
initially hit and application service layer. The application service layer here acts as a facade between presentation and the domain.
There's debate over that but I would consider carefully whether that additional layer is needed or not. It adds a lot of boilerplate code and degrades maintainability - as someone pointed out recently, when you separate things that change for the same reasons (ie your service methods and the corresponding domain methods), you have to make changes in many different places in the system.
On the other hand, you could need that service layer to map your domain objects to DTOs but there again, it could be done directly in the Controller and nothing forces you to use DTOs in the presentation layer.
My confusion is that from a DDD perspective Im not sure whether for
example aggregate roots should perform their own persistance i.e. the
aggregate gets injected with a repository and then persists/fetches
itself or whether as above the application service layer uses
repositories to act on or fetch aggregates?
It's usually considered bad practice to have aggregate roots manage their own persistence because it breaks persistence ignorance and violates the Single Responsibility Principle. If you do that, your aggregate root class now has 2 reasons to change, 2 reasons to break the code, it is less maintainable, etc.
You should instead delegate the responsibility of saving the aggregate root in its repository to an object that will be aware of the application execution context (for instance, a Controller or an object in the Application layer).
Also if the application service layer is injected with all
repositories, does the domain service that the application service
layer calls also need repositories injected?
Yes, I think it pretty much makes sense especially if the domain service heavily relies on the repository.

Domain Driven Programming Using Spring

I have a question on DDD & Spring. I always design my application around anemic domain model and service taking care of business logic/persistence.
Assume you have a spring managed persistence/respository service for a Domain object e.g. Book. If I have to expose a save() method on book then i will need repository bean inside my domain or i will have to look up the context for the repository bean. Which is exactly opposite of Dependency Injection.
Now, If I have repository id injected into domain and domain object is cached ( clustered cache) and then on deserialization it will not have the injected repository service as spring containers will be different.
I might be wrong but if someone can explain me how this scenario will work, it would be of great help
I think that the "facade" of your application should use a Repository (or other infrastructure service) to save the "book". The book should not save it-self, this is responsibility of the Repository.
If you need to make any infrastructure operation (for example, search the database) from a Domain Entity, then you should gain access to this Repository by looking up the context (and getting coupled to Spring as a result) or injecting the Repository through Dependency Injection in the Entity.
The problem is that the "instantiation" of the Entity is not responsibility of Spring but of the Persistence Provider, so Spring cannot handle this injection. What to do?
Well, there are several ways (none of them very "beautyful") to do this:
Through AOP: you can instrument the code with Aspect Oriented Framework (like AspectJ) configuring the system to inject whatever dependency in the Entity in the instantiation moment.
Through a Hibernate interceptor: if your Persistence Provider is Hibernate, it offers you a hook to place interceptors in certain points of the life cycle of the Entities. You can configure an interceptor that looks-up the spring context to inject dependencies in the instantiation of every Entity.
Maybe the easiest way is to implement a little and static "serviceLocator" coupled with spring that looks-up services asked by the Entities when they need them. This service locator is just a layer to avoid your entities to get coupled to Spring.
I think that a "save" method (save in a DB, in example) doesn't belong to the domain object... Does the book "save" itself? Or is the repository saving it?...

Where should "#Transactional" be placed Service Layer or DAO

Firstly it is possible that I am asking something that has been asked and answered before but I could not get a search result back. We define transactional annotations on service layer typical spring hibernate crud is usually
Controller->Manager->Dao->Orm .
I now have a situation where I need to choose between the domain model based on client site.
Say client A is using my domain model all is good but then an other client site would give me a web service and not be using our domain model.
Which layer should I be replacing . I believe it has to be DAO which will be getting me data from web service and sending it back.i.e two separately written DAO layers and plugged in based on scenario.
I have now realized that we have been doing tight coupling (if there is such a thing or say not having loose coupling) when we put #Transactional in Service layer. So many brains can not be wrong or are they (I doubt it).
So question is "Where should "#Transactional" be placed Service Layer or DAO ?" and is it service layer downwards I should be replacing.
Eleven years on and still relevant . If I look back at the project somethings were obviously wrong with my understanding of Domain model back then . I was regarding ORM layer as domain model and we wanted to work with ORM and detached entities and no have any data mapping and not have any DTOs. That was the trend those days. These days Domain Model is not the ORM and having a proper Domain model and using ORM or Webservices are datasources take care of this issue. Like many pointed out yes Service is the right place for it and have proper domain model and not regard JPA (ORM) as domain model.
Ideally, Service layer (Manager) represents your business logic and hence it should be annotated with #Transactional.
Service layer may call different DAOs to perform DB operations. Lets assume a situation where you have 3 DAO operations in a service method. If your 1st DAO operation failed, other two may be still passed and you will end up with an inconsistent DB state. Annotating Service layer can save you from such situations.
You are going to want your services to be transactional. If your DAOs are transactional, and you call different DAOs in each service, then you would have multiple transactions, which is not what you want. Make the service calls transactional, and all DAO calls inside those methods will participate in the transactions for the method.
i will suggest to put #Transactional in Service layer methods since we can have multiple DAO implementations. by using this we can made our services will be transactional. refer
best practice is to use A generic BasicService to offer common services.
The Service is the best place for putting #Transactional, service layer should hold the detail-level use case behavior for a user interaction that would logically go in a transaction. in this way we can have maintain separation between web application code and business logic.
There are a lot of CRUD applications that don't have any significant business logic, for them having a service layer that just passes stuff through between the controllers and data access objects is not useful. In these cases we can put transaction annotation on Dao.
So in practice you can put them in either place, it's up to you.
By having multiple calls in your service you need #Transactional in service. different calls to service will execute in different transactions if you put #Transactional in service.
It's of a personal choice based on application types, if application is layerd across many modules and majority of operations are #CRUD based ,then having #transactional annotation at service level makes more sence.. engine type application like schedulers , job servers,#etl report apps, where sessions and user concept does not exists, then propagational transaction at context level is most suitable... we should not end up creating clusterd transactions by putting #transactional every where ending up transactional anti patters...anyways for pragmatic transaction control JTA2 is most suitable answer...again it depends on weather you can use it in a given situations...
You should use #Transactional at service layer, if you want to change the domain model for client B where you have to provide the same data in a different model,you can change the domain model without impacting the DAO layer by providing a different service or by creating a interface and implementing the interface in different model and with the same service populate the model based on the client.This decision is based on the business requirement and the scope of the project.
i have heard in a programming class,that dao layer is responsible for interacting with database, and service is a set of operations might be with dao and therefore database or not and that set of operation is in one transaction, mean is better service be transactional.

Resources