The Backend for Frontend (BFF) pattern is yet another variation of the Gateway pattern. With Backend for Frontend, instead of building a general-purpose gateway, we build a gateway per user interface (for each application that interacts with the system), lowering the complexity. Moreover, it allows for fine-grained control of what endpoints are exposed. It removes the chances of app B breaking when changes are made to app A. Many optimizations can come out of this pattern, such as sending only the data that’s required for each call instead of sending data that only a few applications are using, saving some bandwidth along the way.Let’s say that our Web App needs to display more data about a device. To achieve that, we would need to change the endpoint and send that extra information to the mobile app as well. However, the mobile app doesn’t need that information since it doesn’t have room on its screen to display it. Next is an updated diagram that replaces the single gateway with two gateways, one per frontend:

Figure 19.22: Two Backend for Frontend gateways; one for the Web App and one for the Mobile App
Doing this allows us to develop specific features for each frontend without impacting the other. Each gateway now shields its particular frontend from the rest of the system and the other frontend. This is the most important benefit this pattern brings: client independence.Once again, the Backend for Frontend pattern is a gateway. Like other variations of the Gateway pattern, it can become the bottleneck of its frontend and its single point of failure. The good news is that the outage of one BFF gateway limits the impact to a single frontend, shielding the other frontends from that downtime.
Mixing and matching gateways
Now that we’ve explored three variations of the Gateway pattern, it is important to note that we can mix and match them, either at the codebase level or as multiple microservices.For example, a gateway can be built for a single client (backend for frontend), perform simple routing, and aggregate results.We can also mix them as different applications, for example, by putting multiple backend for frontend gateways in front of a more generic gateway to simplify the development and maintenance of those backend for frontend gateways.Beware that each hop has a cost. The more pieces you add between your clients and your microservices, the more time it will take for those clients to receive the response (latency). Of course, you can put mechanisms in place to lower that overhead, such as caching or non-HTTP protocols such as gRPC, but you still must consider it. That goes for everything, not just gateways.Here is an example illustrating this:

Figure 19.23: A mix of the Gateway patterns
As you’ve possibly guessed, the Generic Gateway is the single point of failure of all applications, while at the same time, each backend for frontend gateway is a point of failure for its specific client.
A service mesh is an alternative to help microservices communicate with one another. It is a layer, outside of the application, that proxies communications between services. Those proxies are injected on top of each service and are referred to as sidecars. The service mesh can also help with distributed tracing, instrumentation, and system resiliency. If your system needs service-to-service communication, a service mesh would be an excellent place to look.