Is API Gateway needed when using Microfrontends? - api-gateway

When doing microservices it's quite a common and good practice to have a top layer called API-Gateway, that sits in front of a group of microservices, to facilitate requests and delivery of data and services.
When using MicroFrontends to compose an UI app from multiple sub-apps (MFE), I cannot really see a benefit about still using an API gateway to communicate between each MFE and its corresponding Microservice.
In many schemas, an API-Gateway is still used in front of the microservices
Example here :
But the fact that each microfrontend is its own app also probably means it will communicate with its own API. In this case I would either use a thin API layer over each microservice, and then make each MFE communicate directly with this layer, because a MFE probably won't ever need to read data from another MFE (this would go against the spirit of MFE, or am I wrong ?).
What kind of approach would you use in your projects ?

Related

Why do microservices need to communicate with each other?

I'm new with this but in case if we have fronted + few different microservices I just don't get why do we need any of them to communicate with each other if we can manipulate between their data via axios on frontend. What is the purpose of event bus and event-driven architecture in the case if we use both frontend and backend microservices?
Okay, for my example I'm using 5 microservices. There are 2 of them:
Shopping cart
Posts
And I want to access posts microservice directly, pass their data through the event bus, so the shopping cart microservice would have its information. The reason is that posts and shopping cart both have different data bases, so is a good example doing this that way, or just through frontend with axios service?
What you are suggesting could be true for a very simple application, which hardly even needs an architecture such as microservice. It is clear why services need communication:
some services are not even accessable (for various reasons such as security) in client, so a change in them must be initiated in other backend services with such priviledge
some changes are raised in backend services and not client, e.g. a cronjob for doing some task
it would question reusability as you must consider the service to be used by not only client, but in any environment
what would happen if you want your services to be used by public, what if they do not implement part of the needed logic intentionally or by mistake
making client do everything could be so complex and would reduce flexibility
some services such as authentication are acting as a supporting mechanism to ensure safety (or anything other than main logic), these should be communicated directly by the service needing them
As for second part of your question, it depends on several factors like your business needs & models, desired scalability, performance, availability, etc. so the right answer or in another say, the answer that fits would be different.
For your problem, using event bus which is async would not be a good solution as it would hurt consistency in your services. Instead synchronous ways like a simple API call in your posts service would be a better idea.

Why API Gateway is recommended for Microservices?

For microservices, the common design pattern used is API-Gateway. I am a bit confused about its implementation and implications. My questions/concerns are as follows:
Why other patterns for microservices are not generally discussed? If they are, then did I miss them out?
If we deploy a gateway server, isn't it a bottleneck?
Isn't the gateway server vulnerable to crashes/failures due to excessive requests at a single point? I believe that the load would be enormous at this point (and keeping in mind that Netflix is doing something like this). Correct me if I am wrong in understanding.
Stream/download/upload data (like files, videos, images) will also be passing through the gateway server with other middleware services?
Why can't we use the proxy pattern instead of Gateway?
From my understanding, in an ideal environment, a gateway server would be entertaining the requests from clients and responding back after the Microservices has performed the due task.
Additionally, I was looking at Spring Cloud Gateway. It seems to be something that I am looking for in a gateway server but the routing functionality of it confuses me if it's just a routing (redirect) service and the microservice would be directly responsible for the response to the client.
The gateway pattern is used to provide a single interface to a bunch of different microservices. If you have multiple microservices providing data for your API, you don't want to expose all of these to your clients. Much better for them to have just a single point of entry, without having to think about which service to poll for which data. It's also nice to be able to centralise common processing such as authentication. Like any design pattern, it can be applied very nicely to some solutions and doesn't work well for others.
If throughput becomes an issue, the gateway is very scalable. You can just add more gateways and load balance them
There are some subtle differences between proxy pattern and API gateway pattern. I recommend this article for a pretty straightforward explanation
https://blog.akana.com/api-proxy-or-gateway/
In the area of microservices the API-Gateway is a proven Pattern. It has several advantages e.g:
It encapsulate several edge functionalities (like authentication, authorization, routing, monitoring, ...)
It hides all your microservices and controls the access to them (I don't think, you want that your clients should be able to access your microservices directly).
It may encapsulate the communication protocols requested by your microservices (sometimes the service may have a mixture of protocols internally which even are only allowed within a firewall).
An API-Gateway may also provide "API composition" (orchestrating the calls to several services an merge their results to one). It s not recommended, to implement a such composition in a microservice.
and so on
Implementing all these feature in a proxy is not trivial. There is a couple of API-Gateways which provide all these functionalities and more like the Netflix-Zuul, Spring-Gateway or the Akana Gateway.
Furthermore, in order to avoid your API-Gateway from being a bottleneck you may :
Scale your API-Gateway and load balance it (as mentioned above by Arran_Duff)
Your API-Gateway should not provide a single one-size-fits-all API for all your clients. Doing so you will, in the case of huge request amount (or large files to down/up load) for sure encounter the problems you mentioned in questions 3 and 4. Therefore in order to mitigate a such situation your Gateway e.g may provide each client with a client specific API (a API-Gateway instance serves only a certain client type or business area..). This is exactly what Netflix has done to resolve this problem (see https://medium.com/netflix-techblog/embracing-the-differences-inside-the-netflix-api-redesign-15fd8b3dc49d)
1.Why other patterns for microservices are not generally discussed? If they are, then did I miss them out?
There are many microservice pattern under different categories such as database , service etc .This is a very good article https://microservices.io/patterns/index.html
2.If we deploy a gateway server, isn't it a bottleneck?
Yes to some extent .Q3's answers image will answer this.
3.Isn't the gateway server vulnerable to crashes/failures due to excessive requests at a single point? I believe that the load would be enormous at this point (and keeping in mind that Netflix is doing something like this). Correct me if I am wrong in understanding.
4.Stream/download/upload data (like files, videos, images) will also be passing through the gateway server with other middleware services?
Why can't we use the proxy pattern instead of Gateway?
The use case for an API Proxy versus an API Gateway depends on what kinds of capabilities you require and where you are in the API Lifecycle. If you already have an existing API that doesn’t require the advanced capabilities that an API Gateway can offer than an API Proxy would be a recommended route.
You can save valuable engineering bandwidth because proxies are much easier to maintain and you won’t suffer any negligible performance loss. If you need specific capabilities that a proxy doesn’t offer you could also develop an in-house layer to accommodate your use case. If you are earlier in the API lifecycle or need the extra features that an API Gateway can provide, then investing in one would pay dividends.

Communication pattern for MicroFrontends to MicroService backend trough single channel/websocket

we are currently facing some tough architectural questions about integrating multiple Web Components with individual backend services in a composite web UI to one smooth web application.
There are some constraints an (negotiable) design decisions:
A MicroService should serve it's own frontend (WebComponent), we would like to use HTML Imports to allow including such a WebComponent to the composite UI
A frontend WebComponent needs to be able to recieve live updates/events from it's backend MicroService
The page (sum of Web Components used in the composite UI) shall only use one connection/permanent occupied port to communicate with the backend
I made a sketch representing our abstract / non-technical requirements for further discussion:
As of my understanding, the problem could be rephrased to: How do we
a) concentrate communication on entering
b) distribute communication on exiting
the single transport path on both ends.
This two tasks need to be solved on both sides of the transport path, eg. the backend and the frontend.
For the backend, I am quite hopefull that adopting the BFF pattern as not only described by Sam Newman could serve our needs. The right half (backend) side of the above sketch could then look similar to this:
The transport path might be best served using standardized web technologies, eg. https and websocket (wss) for the most times needed, bidirectional communication. I'm keen to learn about alternatives with an equivalent high adoption rate in the web technology sector.
For the frontend we are currently lacking ideas and knowledge about previously described patterns or frameworks.
The tricky thing is, that multiple basically independent WebComponents need to find together for using the ONE central communication path. If the frontend would be realized by implementing one (big) Angular application for example, we would implement and inject a "BackendConnectorService" (Name to be discussed) and inject in to our various components.
But since we would like to use decoupled Web Components, none such background layer for shared business logic and dependency injection exists. Should we write a proprietary JS-library, which will be loaded to the window-context if not present yet from every of our components, and will be used (by convention) to communicate with the backend?
This would roughly integrate to the sketch like below:
Are we thinking/designing our application wrong?
I'm thankful for every reasonable idea or hint for a proven pattern/framework.
Also your view on the problem and the architecture might be helpful to circumnavigate the issues we are facing right now.
I would go with same approach you are using on the backend for the frontend.
Create an HTTP or WS gateway, that frontend components will poll with requests. It will connect to backend BFF and there you solved all your problems. Anytime you want to swap your components, transfer or architecture, one is not dependent on the other.

Backends For Frontends BFFs or API Gateway

In a micro-services architecture we can have:
A single API gateway providing a single API for all clients.
A single API gateway providing an API for each kind of client.
A per-client API gateway providing each client with an API. which is the BFF pattern.
Netflix uses the second style Inside the Netflix API Redesign. we can surely say that they have created a smart-piece of middleware in their architecture that takes on multiple responsibilities.
But how much work this single API back-end can handle, it seems that it can become a bottleneck so easily.
So my question is what are the benefits of choosing the single API to handle requests for more than 1000 clients instead of creating an API Gateway specifically designed to one type of clients? Aren't they facing many challenges to manage and maintain this complex piece?
It all depends where your end users are, in case of Netflix, they have differnt types of clients, web/mobile/streaming sticks/bluray players/what not, while web (updated to latest all the time), mobile (updated to latest eventually), bluray player with pre-installed app for example may never get updated.
And you have to version your apis accordingly for each platform and maintain them based on client update cycle for backward compatibility. If you have too many variations in a single api it will be hard to maintain instead it is easier to write an api for each type of client. Unless you have real need for #3 and have enough resources to develop for each type of client I wouldn't jump into it, as you have to maintain many variations of api for the same purpose.
I would start small with #1.

What is the role of falcor in a microservice architecture?

Say we have following taxi-hailing application that is composed of loosely coupled microservices:
The example is taken from https://www.nginx.com/blog/introduction-to-microservices/
Each services has its own rest api and all services are combined in a single api gateway. The client does not talk to a single service but to the gateway. The gateway requests information from several services and combines them to a single response. For the client it looks like it is talking to a monolithic application.
I am trying to understand: where could we incorporate falcor into this application?
One Model Everywhere from http://netflix.github.io/falcor/
Falcor lets you represent all your remote data sources as a single
domain model via a virtual JSON graph. You code the same way no matter
where the data is, whether in memory on the client or over the network
on the server.
In this taxi-hailing application each microservice represents a single domain model already. Can you think of any benefit we could thrive by wrapping each microservice with falcor? I cannot.
However I think it is very convenient to incorporate falcor into the api gateway because we can abstract away the different domain models created by the microservices into one single or at least a few models.
What is your opinion?
You are right. This is how Netflix uses Falcor and what the Falcor router is designed for.
From the documentation:
The Router is appropriate as an abstraction over a service layer or REST API. Using a Router over these types of APIs provides just enough flexibility to avoid client round-trips without introducing heavy-weight abstractions. Service-oriented architectures are common in systems that are designed for scalability. These systems typically store data in different data sources and expose them through a variety of different services. For example, Netflix uses a Router in front of its Microservice architecture.
It is rarely ideal to use a Router to directly access a single SQL Database. Applications that use a single SQL store often attempt to build one SQL Query for every server request. Routers work by splitting up requests for different sections of the JSON Graph into separate handlers and sending individual requests to services to retrieve the requested data. As a consequence, individual Router handlers rarely have sufficient context to produce a single optimized SQL query. We are currently exploring different options for supporting this type of data access pattern with Falcor in future.
Falcor is really a great api if it is used in the correct way for very relevant use cases, like :
If your page has to make multiple REST end point calls
These calls don't depend on each other
All the REST calls happens on initial page load
Performance : If you want to cache the REST responses (for example, the microservice uses gemfire caching, you may not need falcor cache. You could still use falcor caching if you want to reduce the network latency)
Server requests batching : When running Falcor in node environment, you may want to cut down the amount of calls to node server from the client side.
Easier response parsing : If you don't want the client code to worry about extracting the data-points from REST response (Including error handling)
and so on ..
However, there are plenty of situations where falcor does not serve the purpose as much and feel that it is better off calling the end point directly :
If REST calls are dependent on one another
If you want to pass lot of parameters for calling the end point
If you don't intend to cache the response(s)
If you want to share some secure cookies (ex:XSRF tokens) with the REST web service

Resources