I am facing this problem and would like to review my approach to it here.
- A
Client
sends an HTTP request toService A
and is expecting an answer. Service A
is connected toDB A
. When it receives a request fromClient
, it should save it inDB A
and forward it toService B
. If it already exists, it should return a failure.Service B
is connected toDB B
. When it receives a request fromService A
, it should save it inDB B
. If it already exists, it should return a failure which is propagated back to theClient
How can one design such a system so that:
- The Client does not block forever
DB A
andDB B
DO NOT contain duplicated data- Both services conform to a Microservices architecture (i.e., some downtime is expected).
One way i thought would be good to design it is to split the Client request into two: one to post the data without expecting an answer, and another request to query the data in question if it was successfully inserted. This avoids blocking the client. Both Services would need to have a queue.
Am i overlooking something fundamental in the design?
Many thanks in advance
-
1Request-Response communication between microservices should be avoided. Prefer EDA instead. Without data duplication you lose so many benefits of microservices that you might as well create a monolithic system with a single integration database, why would you want that in a microservices architecture?Rik D– Rik D02/26/2023 10:02:40Commented Feb 26, 2023 at 10:02
1 Answer 1
For this kind of requirement, it will be better to have the client receive an intermediate response rather than returning the final answer. For this to work, I would make a client request processed asynchronously.
In simple terms, Service A and Service B act as consumers listening to queues QueueA
and QueueB
respectively on a message broker service (ActiveMQ, RabitMQ, etc) There will be another service called API service that listens to client requests. This service will also have its own DB maintaining status of tasks (DB API). Service A and Service B will also have access to DB API.
With this design in place, here is how a request is processed when it is submitted by the client:
- API Service will create a task ID in DB API. The task status will be
In Progress
. Then it will post a request toQueueA
. The task ID is retuned as an immediate response. - Service A will consume the message, processes it. If the request is processed successfully, the quest is forwarded to
QueueB
. It will update the DB API against the task ID. - Service B listening to
QueueB
consumes the message and processes it. If it fails, the failure is updated against the DB API against the task ID in DB API as the final result.
Based on the task updates done by Service A and Service B, the status of the task will either be Done
or Error
. The client that is polling for the job to complete, will then get the final result as response.
Explore related questions
See similar questions with these tags.