I am trying to wrap my head around the differences between an API gateway and the aggregator pattern for microservices.
At the moment From my understanding the aggregator pattern functions by collecting pieces of data from various microservices and returns an aggregate for processing.
Now the API gateway is the single entry point that aggregates the calls to the individual microservices. While this may sound very similar to the Aggregator Pattern, there are some distinct features. Most importantly, this new service does not store data but instead becomes responsible for API composition, request routing, and new features such as authentication
I would really like to understand if my reasoning is correct here.
Thank you in advance!
Yes, your understanding is correct. I would add a few ideas:
The API Gateway usually is entry-point of the system, while an aggregator microservice can be somewhere in the middle-layer.
The API Gateway may store partial responses from other microservices, while it waits for other ones to respond (similarly to an aggregator)
There is also a pattern which mixes them, known as a gateway aggregation pattern
Though this seems very similar having a aggregator service vs API Gateway acting as a aggergator.
Think about much bigger ecosystem, where API Gateway would genrally be 1, but we can have number of aggregator services.
Aggregator service will generally lie in middle layer and can be built using specific patterns, these can be Parallel, Chaining or Branching.
Taking example of ecommerce application, we can have below aggregators and more.
Customer Dashboard Aggrgator (Recommeneded products, past orders, current active order etc)
Cart Aggregator (Shipping Service, Inventory Service, Discount Service)
Order History Aggregator
Customer Information Aggregator (Personal Information, Address)
Related
This is probably a bit opinion-based question, but I will try to be technical to still be relevant.
Consider having several microservices: a, b, c.
To make this available on frontend, these could be made available as:
https://host/services/a
https://host/services/b
https://host/services/c
However, the fact that the endpoints are split between differents services are kind of irrelevant for frontend and basically if we can guarantee the endpoints don't clash, it would be great to have these available directly:
a/endpoint1 -> https://host/services/endpoint1
a/endpoint2 -> https://host/services/endpoint2
b/endpoint3 -> https://host/services/endpoint3
c/endpoint4 -> https://host/services/endpoint4
To implement such mapping, one needs to list all endpoint or at least write some matching pattern within the proxy service. This is very nice for the Frontend team to work with, however it is unfortunately very easy to brake.
What are the best practices for mapping the urls of microservices? Only thing which comes to my mind are some exports of OpenApi, which could be handled by FE to get the right path. However, every service generates its own OpenApi json, so we are basically back to the original problem.
are you sure the Frontend team needs ALL the exposed endpoints? Usually, frontends talk with an API Gateway, or, as cool kids call them these days, "Backend for Frontends".
In a nutshell, it's a special service that takes care of exposing only the functionalities/endpoints needed by the frontend. It will forward calls to the relevant services or, if necessary, call multiple services and aggregate the results.
In most cases these API Gateway don't have a db, as they're retrieving all the data from other services. They might however make use of a caching layer to speedup things.
You can even have multiple API Gateway, one per Frontend (eg. desktop, mobile).
Let say I have 22 microservices. I developed with docker on local.
Client wants to get product model data which contains 3 different service data and aggregate them.
Should I use aggregator gateway api or SPA get separately from each service. Does Aggregator service couple services ?
These Microservices patterns always come with Trade-offs. Here you need to consider more than just a coupling issue when you are going with Aggregator pattern (Backend for Frontend).
The following are some of the points you need to think about before going with this pattern.
The Latency problem. If you want this implementation to make it better without any latency problem, then your services and aggregator should be in the same location or the same data center. Avoid third party calls from aggregators.
This can introduce a single point of failure. Make sure that you've designed in such a way that the service is highly available.
Implement a resilient design and timeout since this aggregator is calling other services and getting data. If one or more service calls take too long, it should timeout and return a partial set of data. Consider how your application will handle this scenario
Monitoring of your aggregator and it's child service calls. Implement distributed tracing using correlation IDs to track each call.
Ensure the aggregator has the adequate performance to handle the load and can be scaled to meet your anticipated growth.
These are the best practices that I can suggest, You are the best person who can decide based on your system requirements and these points.
There are some compelling advantages to using a BfF service as an orchestration layer that aggregates calls to various backend data services.
It will reduce the complexity in the data access areas of your SPA.
It can also reduce load times.
Over time, your frontend devs will be less likely to get blocked on the backend devs assuming that the BfF is maintained by the frontend devs.
Take a look at this article on Consistency, Coupling, and Complexity at the Edge that goes into more detail on this and proposes some best practices such as GraphQL vs REST.
I'm developing an application that must both handle events coming from other systems and provide a REST API. I want to split the applications into micro services and I'm trying to figure out which approach I should use. I drew attention to the Spring Cloud Netflix and the Spring Cloud Data Flow toolkit, but it's not clear to me whether they can be integrated and how.
As an example, suppose we have the following functionality in the system:
1. information about users
card of orders
product catalog
sending various notifications
obtaining information about the orders from third-party systems
processing, filtering, and transformation of order events
processing of various rules based on orders and sending notifications
sending information about user orders from third-party systems to other users using websockets (with pre-filtering)
Point 1-4 - there I see the classical micro service architecture. Framework - Spring Netflix Stack.
Point 5-9 - it's best to use an event-driven approach. Toolkit - Spring Data Flow.
The question is how to build communication between these platforms.
In particular - POPULATE ORDER DETAILS SERVICE must transform the incoming orders and save additional information (in case it needed) in the database. ORDER RULE EXECUTOR SERVICE should obtain information about the current saved rules, execute them and send notifications. WEB SOCKET SERVICE should send orders information only if a particular user has set the filters, and ORDER SAVER SERVICE should store the information about the transformed orders in the database.
1.
Communication between the micro-services within the two platforms could be using the API GATEWAY, but in this case, I have the following questions:
Does the Spring Cloud platform allow to work with micro services that way?
Performance - the number of events is very huge, which can significantly slow down the processing of events. Is it possible to use other approaches, for example, communication not through the API Gateway but through in-memory cache?
2.
Since some functionality intersects between these services, I have a question about what is "microservice" in the understanding of the Spring Cloud Stream framework. In particular, does it make sense to have separate services? Can the microservice in the Spring Cloud Stream have a REST API, work with the database and simultaneously process the events? Does such a diagram make sense and is it possible to build such a stack at the moment?
The question is which of these approaches is more correct? What did Spring Data Streams mean by "microservice"?
Given the limited information in the post, it is hard to convince on all the matters pertaining to this type of architecture, but I'll attempt to share some specifics, and point to samples. Also for the same reasons, it is hard to solve for your needs end-to-end. From the surface, it appears you're attempting to build event-driven applications and wondering whether Spring Cloud Stream (SCSt) and Spring Cloud Data Flow (SCDF) could help.
They can, yes.
The Order, User, and Catalog seem like domain objects and it would all come together to solve for a use-case. For instance, querying for a number of orders for a particular product, and group by the user. There are a few samples that articulate the data flow between the entities to solve similar problems. Here's a live code-walkthrough of event-driven systems in action. There's another example of social-graph application, too.
Though these event-driven applications can run standalone as individual services with the help of of message broker (eg: Kafka or RabbitMQ), you could of course also register them in SCDF and use them in the SCDF DSL to build a coherent data pipeline. We are expanding on more direct capabilities in SCDF for these types of use-cases, but there are ways to orchestrate them today with current abilities, too. Follow spring-cloud/spring-cloud-#2331#issuecomment-406444350 for more details.
I hope this gives an idea. Try to build something small using SCSt/SCDF, prove it out, and expand to more complex use-cases.
We are splitting a monolith application into microservices. This will be a gradual process, it means initially we will start with 2 microservices, later we will split them into more and so on.
The monoligh exposes a REST API which provides methods for managing tens of different entities (e.g. users, user_types, roles, role_types, etc.). There is only one consumer of the REST API exposed by the monolith - a Javascript frontend app.
We are currently investigating two possibilities how to configure the API gateway (Zuul):
URLs will contain the microservice name, e.g. /api/dictionary will serve /api/dictionary/user_types and /api/dictionary/role_types, while /api/data will serve /api/data/users and /api/data/roles. It means the URLs will change over time as we create more microservices. Everytime we do it the consumer (frontend) will have to be changed.
URLs will be based on the entity names, e.g. /api/users, /api/user_types, /api/roles and /api/role_types. The disadvantage is that the Zuul configuration will have to contain an explicit configuration for every single entity managed by the system.
Which of the above approaches is correct?
Manmay saying is correct. You should go with first approach for long term gain.
If you still want alternative, then you can combine both of these approach by configuring your API gateway in such a way that, It will route your request
/api/users -> /api/data/users
/api/user_types -> /api/dictionary/user_types
/api/roles -> /api/data/roles
/api/role_types -> /api/dictionary/role_types
By this approach, you will not have to compromise any of the concerns like maintenance or client side changes.
I am building out a microservice architecture and kinda confused on one part. I am using Kafka as a message broker system to communicate within my services. A perfect example would be Uber's API for request estimation. It returns duration, distance, price, etc. I would assume they have a microservice for each of those, i.e. service for pricing, service for duration/distance, service for drivers, etc. My question is when hitting the endpoint /requests/estimate does the requests microservice make rest calls to the other microservices to retrieve data for the duration, distance, etc? or does the API Gateway take care of that?
I say it depends on the use case. If service A needs to know what service B knows, then it is perfectly sane for service A to make a REST call to service B. But if the combined knowledge for A and B is only needed in your gateway then the gateway can combine the results.
Both are perfectly valid ways of doing it, but I would go the Estimate microservice way to avoid putting too much logic in the API Gateway.
Maybe in the future your estimation calculation will change, and it wouldn't make much sense to me to update the gateway every time.
In practice, not all gateway APIs support multiple calls and aggregation. In the micro service architecture, there is a common pattern ("API Composition", "Composition Patterns" in particular "Aggregator Pattern"), the idea of which is that you need to make a separate service that will contain the business logic of multiple calls and aggregation.