I'd like to use the microservices architectural pattern for a new system, but I'm having trouble figuring out how to share and merge data between the services when the services are isolated from each other. In particular, I'm thinking of returning consolidated data to populate a web app UI over HTTP.
For context, I intend to deploy each service to its isolated environment (Heroku) where I won't be able to communicate internally between services (e.g. via //localhost:PORT
. I plan to use RabbitMQ for inter-service communication, and PostgreSQL for the database.
The decoupling of services makes sense for CREATE operations:
UserId
submits 'Join group' webform on the frontendGroupJoinRequest
including the UserId
is added to the RabbitMQ queueGroups
service picks up the event and processes it, referencing the user's UserId
However, READ operations are much harder if I want to merge data across tables/schemas. Let's say I want to get details for all the users in a certain group. In a monolithic design, I'd just do a SQL JOIN
across the Users and the Groups tables, but that loses the isolation benefits of microservices.
My options seem to be as follows:
To view all the Users
in a Group
, a site visitor gets a list of UserID
s associated with a group from the Groups service, then queries the Users
service separately to get their names.
Pros:
Cons:
A public API server handles request endpoints. Application logic in the API server makes requests to each service over an HTTP channel that is only accessible to other services in the system.
Pros:
Cons:
Given I've already got RabbitMQ running, I could just use it to queue requests for data and then send the data itself. So for example:
GetUsersInGroup
event with a RequestID
Groups
service picks this up, and adds the UserID
s to the queueRequestID
, waits for the responses, merges the data into the correct format, and sends back to the clientPros:
Cons:
VIEW
sServices are isolated into database schemas. Schemas can only be written to by their respective services. Services expose a SQL VIEW
layer on their schemas that can be queried by other services.
The VIEW
functions as an API contract; even if the underlying schema or service application logic changes, the VIEW
exposes the same data, so that
Pros:
Cons:
I'm leaning toward the last option, but would appreciate any thoughts on other approaches.
To evaluate the pros and cons I think you should focus on what microservices architecture is aiming to achieve. In my opinion Microservices is architectural style aiming to build loosely couple applications. It is not designed to build high performance application so scarification of performance and data redundancy are something we are ready accept when we decided to build applications in a microservices way.
I don't think you services should share database. Tighter coupling scarify the main objective of the microservices architecture. My suggestion is to create a consolidated data service which pick up the data changes events from all the other services and update the database behind it. You might want to design the database behind the consolidated data service in a way that is optimised for query (like a data warehouse) because that's all this service will be used for. You might want to consider using a NoSQL database to support your consolidated data service.