Due to the popularization of service offerings on the internet, consuming and making APIs available to third parties has created many business opportunities for the most diverse segments.
In addition to communicating with each other,api-gateway, that is, users, client applications, third-party applications, etc. For this end, mechanisms are needed to expose the functionality offered by the services “to the world”, whatever the software architecture they use – for example, microservices.
API Gateways that separately analyze the details of the application (how the services are implemented and how they collaborate with each other to run a certain functionality) are a way to meet this need. API Gateway is responsible for transferring requests from the outside world to the application and for transforming or combining their responses to then return the result to the outside world.
In addition to isolating services from the outside world, API Gateway also concentrates several common responsibilities of a distributed system, such as load balancing, authenticating, establishing security policies, managing caches, setting limits on the number of external calls and volume of data traffic, in addition to statistical records and log records referring to calls from the outside world.
API Gateway is an elegant solution that brings great benefits when exposing the functionality of services on the internet. It can however become complex, as it becomes the only point of interaction with all the elements of the outside world. The complexity increases when an API Gateway meets requests from very different applications (for example, web applications and apps) and interacts with several services. In such cases, complementing this approach with a Backend For Frontend (BFF) pattern can be quite appropriate.
Backend For Frontend acts as an adapter matching the generic service offering to the specific need of each client.
A typical example is the use of Backend For Frontend when building two different types of user interface – web and mobile – for the same application. In this case, each interface usually has different consumption needs regarding the functionalities offered by the same services. Typically, the mobile application needs condensed information. A single screen often requires information from several different services. At the same time, due to the common bandwidth limitation of mobile networks and the need to save battery, it is desirable to reduce the number of calls to a lower quantity than what the application can support.
On the other hand, the web interface requirements are a lot more flexible. It gives more detailed information while not having to save communication bandwidth or avoid traffic of larger volumes of data. In this situation a specific Backend For Frontend can be used for each application, as shown in the picture below (example of an application with microservice architecture), to avoid duplicating the functionality of the services or making them dependent on the types of customers that such services have.
In this example, each Backend For Frontend could also be built as a microservice and benefit from the infrastructure available for its own execution.
In a way, using the Backend For Frontend pattern is equivalent to creating several different APIs for the functionalities of the same services.
Another potential approach would be to create a kind of super API that would allow the consumer to define the shape of response that they desire. In order to build this super API a query language can be used, such as GraphQL. It would allow consumers to specify what information they want and use multiple sources/resources in a single query.