[Seeking advice] RESTful backend on top of distributed microservices
Hi, there!
First of all, I hope this is the adequate subreddit for this post. If it's not, please pardon my inexperience.
I'm looking for help for architectural / pattern design for a concrete use case I'm facing at work. I work as sw. architect in the frontend team of a large company which is building a financial cloud platform. However, we will be leading and probably building a new backend or design a solution for the problem at hand:
We currently have several distributed services which expose RESTful microservices in the platform (one for resources scaffolding, another one for deployments and deployment control, another for monitoring clusters/resources, logging and alarms, another one provides aggregated platform status, etc). Security IS a pain but it's already been sorted out, as well as connectivity. We are building a modular web RIA with very complex UI which we want to be showing lots of aggregated data and provide a rich UX (all sorts of filtering, sorting, heterogeneous trees, paging/buffered lists, charts, etc.).
Right now every module has been deployed as an isolated app and connected to "its own" backend or set of microservices, and their functionality has been limited in most cases in line with the amount of data already exposed by such microservices.
We now need to build a backend/proxy/layer/whatever that can connect with the rest or (we would like this one better) even replace them.
However, there is a unique source of truth but distributed among many services (for example, one service might yield an array with the IDs of the project a user has access to, while another might provide us with the details for a project given its id). Currently, one of our backend's endpoints first retrieves the list of IDs, then fires a request for every ID, and then aggregates the result as a single JSON. This is suboptimal. Furthermore, when we want to implement sorting, it is not feasible for someone with access to 200 projects to wait for 200 requests and then sort (in frontend, if you don't want to overload the server with every page request). We can and will have to (regardless of the solution chosen, probably) ask our colleagues in every team to create new endpoints with listing and sorting whenever possible. However, this means going case by case and, sometimes, maybe 3 services/teams can be involved to generate a JSON result with data sparse among them.
Given that we cannot rewrite the platform, and you have N systems and your data might be distributed across microservices on such systems, would anyone be able to suggest a pattern or any ideas on how to create RESTful services that compose larger JSONs (likely not reusable) to be consumed by our RIA/s and be able to perform things like sorting, paging and filtering?
I'm sorry for the wall of text, and thanks a lot for your time and attention.
Posted Feb 5, 2019, 9:29 PM UTC · edited
Wow, a question on Reddit that I am finally ideally suited to answer!
In short, yes, there is a solution for this. It's a common problem when you go from a monolith to a microservice architecture on the back-end. The whole point of microservices is to make them isolated from each other. That, of course, causes problems like what you're running into. As you start to layer microservices on top of each other, dependencies become difficult to manage and can cause performance problems.
The solution is simple but can be tricky to implement if it's your first time doing it. You need to implement an event-based architecture. And then create projections and read models. That will solve your performance issues.
If you don't already have an event-based architecture, you can retrofit it. It's not too hard.
Here is how this works in a nutshell. Microservices emit events on a state change. Other microservices listen to events emitted by microservices they depend on. They then project those events onto a data model that is read-only. Finally, when a higher-level microservice some data from a lower-level microservice, it doesn't need to necessarily call the dependent service. Instead, it can immediately get the data it needs from its local read model projection.
Let me know if you have questions. I love talking about this. I have a blog, too, that talks about event-based architectures. Don't want to advertise here but if you're interested, let me know and I'll send you the link to it via DM.
Source: Principal software architect for a ride-sharing company and founder of an event-sourcing platform as a service.