Is the Controller in MVC considered an application service for DDD? - model-view-controller

I am applying DDD for the M part of my MVC and after some research (studying up!), I have come to the realization that I need my controller to be interacting with domain services (in the model). This would make my controller the consumer of the domain services and therefore an application service (in DDD terms). Is this accurate? Is there a difference between a controller and what DD defines as an application service?

The application layer is somewhere between the domain layer and the presentation layer. The controller is part of the presentation layer, sends commands or queries to the application layer, where the application services execute them using the services and objects of the domain model. So controllers are different from the application services, and they are probably bound to the actual communication form, e.g. HTTP. You should not call domain services from controllers directly, this might be a sign of misplaced code.
Domain Driven Design: Domain Service, Application Service
Domain Services : Encapsulates business logic that doesn't naturally fit within a domain object, and are NOT typical CRUD operations -
those would belong to a Repository.
Application Services : Used by external consumers to talk to your system (think Web Services). If consumers need access to CRUD
operations, they would be exposed here.
So your service is probably an application service and not a domain service, or some part app services, some part domain service. You should check and refactor your code. I guess after 4 years this does not matter, but I had the same thoughts by an application I am currently developing. This app might be too small to use DDD on it, so confusing controllers with app services is a sign of overengineering here.
It is an interesting question when to start add more layers. I think every app should start with some kind of domain model and adapters to connect to that domain model. So if the app is simple enough, adding more than 2 layers might be not necessary. But that's just a thought, I am not that experienced with DDD.

The controller is not considered a service in DDD. The controllers operate in the UI tier. The application services gets data from the DB, validates data, passes data to client (MVC could be a client but so could a request coming from a winforms app) etc etc.
All the controller is doing is servicing requests from the UI. Its not part of the application domain.

In DDD Reference controllers are not mentioned at all. So I think from DDD POV the answer is undefined. So I would consider more practical question: "Do we need to separate Controllers and Application Service"?
Pros:
Separating input processing from use case implementation.
Cons:
Extra layer of indirection that complicates understanding of simpler cases. (It is also annoying to implement some trivial thing by pulling data though many layers without anything actually being done).
So I would choose separation of controller and application service if input processing obfuscates use case logic. I would choose to keep use case logic in controller if both are simple enough so that you can easily see in code use cases separately from input processing.

A Layered Architecture splits the application up into UI-Layer, App-Layer, Domain Layer and Infrastructure Layer (Vaugn Vernons Implementing Domain-Driven Design (location 2901)). The controller falls in "Application Layer" of this broader design architecture and will therefore interact directly with the domain services in the model and is considered an application service. Not only that, it'll will obviously also use the entities and aggregates as available.

Related

Running multiple Quarkus instances on one machine

I have an application separated in various OSGI bundles which run on a single Apache Karaf instance. However, I want to migrate to a microservice framework because
Apache Karaf is pretty tough to set up due its dependency mechanism and
I want to be able to bring the application later to the cloud (AWS, GCloud, whatever)
I did some research, had a look at various frameworks and concluded that Quarkus might be the right choice due to its container-based approach, the performance and possible cloud integration opportunities.
Now, I am struggeling at one point and I didn't find a solution so far, but maybe I also might have a misunderstanding here: my plan is to migrate almost every OSGI bundle of my application into a separate microservice. In that way, I would be able to scale horizontally only the services for which this is necessary and I could also update/deploy them separately without having to restart the whole application. Thus, I assume that every service needs to run in a separate Quarkus instance. However, Quarkus does not not seem to support this out of the box?!? Instead I would need to create a separate configuration for each Quarkus instance.
Is this really the way to go? How can the services discover each other? And is there a way that a service A can communicate with a service B not only via REST calls but also use objects of classes and methods of service B incorporating a dependency to service B for service A?
Thanks a lot for any ideas on this!
I think you are mixing some points between microservices and osgi-based applications. With microservices you usually have a independent process running each microservice which can be deployed in the same o other machines. Because of that you can scale as you said and gain benefits. But the communication model is not process to process. It has to use a different approach and its highly recommended that you use a standard integration mechanism, you can use REST, you can use Json RPC, SOAP, or queues or topics to use a event-driven communication. By this mechanisms you invoke the 'other' service operations as you do in osgi, but you are just using a different interface, instead of a local invocation you do a remote invocation.
Service discovery is something that you can do with just Virtual IP's accessing other services through a common dns name and a load balancer, or using kubernetes DNS, if you go for kubernetes as platform. You could use also a central configuration service or let each service register itself in a central registry. There are already plenty different flavours of solutions to tackle this complexity.
Also more importantly, you will have to be aware of your new complexities, but some you already have.
Contract versioning and design
Synchronous or asynchronous communication between services.
How to deal with security in the boundary of the services / Do i even need security in most of my services or i just need information about the user identity.
Increased maintenance cost and redundant side code for common features (here quarkus helps you a lot with its extensions and also you have microprofile compatibility).
...
Deciding to go with microservices is not an easy decision and not one that should be taken in a single step. My recommendation is that you analyse your application domain and try to check if your design is ok to go with microservices (in terms of separation of concenrs and model cohesion) and extract small parts of your osgi platform into microservices, otherwise you mostly will be force to make changes in your service interfaces which would be more difficult to do due to the service to service contract dependency than change a method and some invocations.

Why does most of the diagram of stateless microservice have the database inside the service and stateful microservice has external database?

Because as I understand it stateless micro service do not rely on state. So why does it need the database inside the micro-service? I thought it should be other way around.
I hope the location of database does not matter as long as the idea of the stateless is that the server will not store any session or any state but it will be stored in a database. While stateful ones do store session and other stuff.
Most of the diagrams related to Microservices architecture have database associated with a service. This is to display the fact that independent micro services have independent databases. In traditional monolith apps, the app would be connected to a single database. When we break a monolith into multiple micro services using domains, the ideal way is for each micro service to have a different database so that services can run and evolve independently. This is a true microservices architecture.
So, to answer your question, database in a micro service block in a diagram just shows the independence of the service with its own data model and logic.

What is the use of service layer in Spring Boot applications?

I am new to Spring Boot and I am creating a RESTful API with no UI.
I am thinking if I should use business service and call repository from there or just call the repository directly from my REST controller?
Separation of concerns is the key:
The controller (presentation layer, or port) is a protocol interface which exposes application functionality as RESTful web services. It should to that and nothing more.
The repository (persistence layer, or adapter) abstracts persistence operations: find (by id or other criteria), save (create, update) and delete records. It should to that and nothing more.
The service layer (domain) contains your business logic. It defines which functionalities you provide, how they are accessed, and what to pass and get in return - independent on any port (of which there may be multiple: web services, message queues, scheduled events) and independent on its internal workings (it's nobody's business that the service uses the repository, or even how data is represented in a repository). The service layer may translate 1:1 from the repositiory data, or may apply filtering, transformation or aggregation of additional data.
The business logic may start simple in the beginning, and offer not more that simple CRUD operations, but that doesn't mean it will forever stay this way. As soon as you need to deal with access rights, it's no longer a matter of routing requests from the controller directly to the repository, but checking access and filtering data as well. Requests may need validation and consistency checks before hitting the database, rules and additional operations may be applied, so your services get more value over time.
Even for simple CRUD cases, I'd introduce a service layer, which at least translates from DTOs to Entities and vice versa.
Keep your controllers/repositories (or ports and adapters) stupid, and your services smart, and you get a maintainable and well-testable solution.
Service layer is not a concept exclusive from Spring Boot. It's a software architectural term and frequently referred as a pattern. Simple applications may skip the service layer. In practical terms, nothing stops you from invoking a repository method from the controller layer.
But, I strongly advise the usage of a service layer, as it is primarily meant to define the application boundaries. The service layer responsibilities include (but are not limited to):
Encapsulating the business logic implementation;
Centralizing data access;
Defining where the transactions begin/end.
Quoting the Service Layer pattern from Martin Fowler's Catalog of Patterns of Enterprise Application Architecture:
A Service Layer defines an application's boundary and its set of available operations from the perspective of interfacing client layers. It encapsulates the application's business logic, controlling transactions and coor-dinating responses in the implementation of its operations.

Why we need to write business logic in separate service layer instead of writing in controller itself?

Whats the use of creating different layer i.e. Service layer for business logic implementation instead of implementing that business logic in Controller itself
It is because of Separation of concerns.
In Controller which is primarily interested in handling incoming http request and responding back to that request. We are worried about things related to handling stuff related to a given communication channel.
You can expose an rest api as well soap api or you may have various formats int which you would want to share the data. Biz logic as such does not care about how you are communicating this data to end users. So you take it out and keep in one common place that only deals with biz logic while the controller class just calls this. You can then have a rest controller and soap controller answering request via same piece of biz logic code.
What you do in controller is validate the request call the service and handle exception in way you want it to be exposed to the caller.
It depends on your architecture. If you're using some of the Domain Driven Design principles, there would be little if any logic in the controllers/api. The controllers would be used to coordinate/ manage the communication between the domain services (i.e. AccountService), repositories (i.e. AccountRepo), and or infrastructure services (i.e. EmailService). All logic would be in the models and services. Some advantages are...
1. Unit testable code
2. The code better models the business problem (controllers mean nothing to the business problem)
3. Controllers don't become a place to jam a lot of business logic into and result into a tangled mess
4. And more...
Of course this all depends on whether maintainability is a priority

Do individual microservices in an orchestration interact with each other?

My product is migrating to microservices and they have presented an architecture where there are 2 parts:
Micro App : This is UI + an Orchestration layer.
Microservices : The individual microservices that micro app interacts with.
Now, in this architecture, they said that the individual microservices can interact with each other directly despite the presence of the orchestration layer. This is contrary to what I read (and understood). My understanding is that individual microservices don't interact with each other directly if there is an orchestrator. Is my understanding correct?
My understanding is that individual microservices don't interact with each other directly if there is an orchestrator. Is my understanding correct?
Yes, you are correct.
In orchestration, by definition, there is a central brain that do the all the communication between microservices. The idea is that individual microservices do not know of each other, so how can they interact with each other?
For more information you can read this book, page 43.

Resources