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

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

Related

Contract Testing - Spring Boot Microservices with external SOAP/REST downstream services

We have a set of microservices communicating with each other and some external downstream services. Spring Cloud Contract is used for integration tests to check the service interfaces. I'm able to test the contracts for communication between the microservices.
I'd like to know how to write the contract tests for a producer which
doesn't provide any contracts (cannot access source code)
SOAP-based
Can I impose the contracts from the consumer itself?
Couldn't find the SCC documentation helpful in this regard. Any helpful pointers are appreciated. Thanks!
If it's SOAP based then it's a standard XML based communication. You can generate XML based contracts (an example is here https://docs.spring.io/spring-cloud-contract/docs/current-SNAPSHOT/reference/htmlsingle/#contract-dsl-xml ). Now as for the one where you don't have access to source code, what you can is the following:
You can create a test that will go via a proxy (e.g. WireMock proxy) to the real application and that way you will store that communication in a form of stubs (https://www.youtube.com/watch?v=ZyHG-VOzPZg), you can also check the code (https://github.com/spring-cloud-samples/the-legacy-app/tree/master/stubs_with_proxy). The problem here is that the producer might not be idempotent or may require a lot of concrete setup on the input to get proper response (e.g. a precisely defined date).
You can create contracts on the consumer side, tell stubrunner where they lay (https://docs.spring.io/spring-cloud-contract/docs/current-SNAPSHOT/reference/htmlsingle/#features-stub-runner-stubs-protocol) and turn the generateStubs feature (https://docs.spring.io/spring-cloud-contract/docs/current-SNAPSHOT/reference/htmlsingle/#features-stub-runner-generate-stubs-at-runtime), example of code (https://github.com/spring-cloud-samples/spring-cloud-contract-samples/blob/master/consumer_with_latest_2_2_features/src/test/java/com/example/GenerateStubsTest.java). The problem here is that as a consumer you can write whatever you want and it might not have anything to do with reality. On the other hand you already have the contracts that you could upload to the producer side with a request that they implement their part one day.
It's up to you to decide which one you prefer, bearing in mind that each of the solutions might have its issues.
As for Pact, Pact follows the second approach since it's the consumer that defines how the interaction should look like. That again might have nothing to do with reality.

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.

To wrap back-end system clients or not in Spring

I have an application with Spring, and I need to call many different types of back-end systems (legacy mainframe, ESB, RESTful...). If we take e.g. REST, I can implement a RESTful client with e.g. RestTemplate. I can A) have developers use RestTemplate client directly, to which they pass the service url and dataobject. Or I can B) wrap RestTemplate inside our own, back-end specific client and offer explicit methods that developers can use. The methods themselves would then ofcourse use RestTemplate and make the explicit back-end calls.
The good with A) is that changes in back-end systems to not need changes to client. Downside is that we don't hide the architecture. B) is more clear for developers and easier to "manage", but changes to back-end systems require us to update all applications that want to use the new back-end functionality. Even worse, a change in back-end system functionality may require all services to be updated.
Still, I am personally leaning towards option B), because it is provides such a nice separation of business logic and architecture services for developers.
I don't understand how you came to the conclusion that clients don't need an update (option A) if they want to use new functionality or if the API breaks because of a change.
I think option B is better. But I would use the HTTP client Feign to create request templates and then publish the interfaces. This way you won't even have to wrap a RestTemplate and manually implement every request.

REST API Layer Orchestration using Spring Integration

We have around 6 individual REST services which we would be calling in our orchestration layer. for example "Calling service-1 to check if a bank account is of certain type, if yes, then call service-2, else call service-3".
Is Spring Integration messaging framework is a right tool for orchestrating calls to those services or its an overkill? Please suggest if there is a better way to accomplish the same.
I can't suggest you better tool, because Spring Integration was the best one for me in the past and now it is my full time job. So, try to find other answers somewhere else.
Now about the point of orchestration with the Spring Integration. To be honest it's just a word which tries to describe the business logic in one application when it calls other external application according some conditions.
So, from big height having HTTP adapters in the Spring Integration, Transformers, Splitters, Routers and Gateways between them, we can say with confidence that messaging layer on Spring Integration fits your requirements and really can help you to distinguish business logic from the orchestration logic.
Not sure what to say else, but I can recommend take a look to the Spring Integration Reference Manual and pay attention to the Routing Slip and Scatter-Gather patterns.

Is the Controller in MVC considered an application service for DDD?

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.

Resources