In our organisation, we have a central service to raise tickets. Let's call this service MainService
. Agents log into this service directly and create raise tickets for various concerns.
A new requirement is to allow users to access this MainService
via a separate new application say MainServiceManagementService
. This new service will provide better user experience and will use APIs exposed by MainService
to perform actions such as fetching list of tickets, viewing details or a ticket, creating tickets and so on.
The MainServiceManagementService
is going to be a central service and will be used by other services to manage tickets pertaining to those specific services. Let's say we have 3 such services namely project A, project B and project C. For each of these services, we will create separate packages in MainServiceManagementService
and they are required to implement their own logic and own response formats.
Let's say I design a central interface like:
interface MainApplicationServiceInterface {
TicketViewResponse viewTicket(TicketViewRequest request);
TicketCreateResponse createTicket(TicketCreateRequest request);
TicketUpdateResponse updateTicket(TicketUpdateRequest request);
}
And then create implementations of above interface for each project such as:
class ProjectAService implements MainApplicationServiceInterface {
// methods implemented here
}
class ProjectBService implements MainApplicationServiceInterface {
// methods implemented here
}
My issue is for project A, I might want to generate a different type of response for view, create, update etc methods compared to project B and so on. The plan would be to take response like TicketViewResponse
and cast it to necessary response class. But I want to have different return types for my method implementations. Also different methods like view, create will have different type of response as shown in interface example. What would be the best way to achieve such a use case?
CodePudding user response:
I truly believe that this issue has nothing to do with Spring or any other framework, but your system design.
We can achieve what you desire by using Generic. You can design your MainApplicationServiceInterface like this :
interface MainApplicationServiceInterface<R extends BaseRequest, P extends BaseResponse>{
P viewTicket(R request);
P createTicket(R request);
P updateTicket(R request);
}
And then in your service implementation, you can define your own set of Request and Response objects, that work their own way.
class ProjectAImplementation implements MainApplicationServiceInterface<ProjectARequest,ProjectAResponse>{
ProjectAResponse viewTicket(ProjectARequest request);
///...further implementation
}
This brings you flexibility, but I'm not very sure if it's optimized for your case. As you're trying to implement 3 separate projects, with different logic, different input types, and different output types. And I feel like, in the future, one of the projects will change, and it may no longer ensure the contract of the interface.
So, be simple, just separate it, completely.
CodePudding user response:
You don't need to do that. The HTTP API of the main service already served the purpose of the java interface for project a and project b.
And this is the characterise of microservice . Each services are different processes which usually communicate with each other through HTTP API. The contract between a client and a service should be defined by the HTTP API but not a java interface.
So just tell project a and project b to follow the HTTP API requirement defined by the main project for their implementation. No need to define such contract in term of java codes and then share with them. It is redundant and just make thing complicated.