Backend For Frontend (BFF) -- Tailored Back Ends for Better UX
What architectural patterns can we use to improve the UX? As this article explains, BFF (Backend for Frontend) optimizes the API design for the best performance and UX.
Discover how at OpenReplay.com.
Before the advent of mobile devices and tablets as a means of interacting with front-end applications, desktop computers were the primary source of data requests and network sessions with a backend service .
The ease at which requested data was formatted and deployed via the web for desktop computers was seamless and hitch-free. The design pattern employed by early software engineers involved the implementation of a general-purpose backend system that manages the application’s underlying functionality and logic.
However, with advancements in internet-enabled devices, the workload on our application’s server also increased, resulting in constant maintenance and the addition of functionality as required over time to support the different types of interactions we were attending to.
This architectural style has advantages, including the accessibility it provides for different frontend interfaces to make network requests to a single backend system.
Nonetheless, the limitations of a single backend service attending to requests from different client interfaces affected the user experience of web and mobile clients interacting with modern frontend applications.
One difficulty users experienced when interacting with an application server on a mobile device was the limited screen space of mobile devices compared to a desktop computer, which made the aggregation, structuring, and formatting of complex data more challenging for mobile clients. Additionally, the single backend service provides network responses to multiple frontend interfaces. This means that the backend system can be difficult to maintain and scale to accommodate new features for the variety of interfaces it responds to.
The Backend for Frontend (BFF) pattern was introduced into the software development and construction workflow to mitigate these observed limitations and correct performance issues.
BFF Architecture: Conceptual Overview
The BFF architectural pattern provides a custom backend API between frontend applications and the backend services responding to clients. The API service provided by a BFF pattern defines a contractual agreement between the frontend interfaces and the architectural pattern of the backend systems catering to requests from clients.
As the name suggests, BFF implements tailored APIs that are hardwired to the requirements and specific needs of each frontend interface interacting with an internet-facing application. The image above illustrates how the services provided by a BFF pattern are structured to fit into the design and functionality of the overall architecture of the backend service by receiving requests from different client interfaces and routing them to the appropriate handler functions of the application server.
Scalability, which refers to the system’s ability to handle a growing amount of work by adding resources to its backend service, is one of the highest-quality attributes employed by software engineers when building modern internet applications.
The API services provided by a BFF pattern ensure the scalability and reliability of internet-facing applications by acting as a middleware layer between frontend interfaces and an application server.
Key Benefits of BFF Tailored APIs
Here are a few upsides we get when we incorporate services provided by a BFF pattern into our construction process:
-
Customizing APIs for different frontends (web, mobile, etc.): The BFF pattern provides tailored APIs designed to cater to the unique needs of different frontend interfaces interacting with an application server. By creating custom API services for specific frontends, client requests can be processed by dedicated BFF APIs rather than being processed uniformly by a traditional backend server, which can result in a bottleneck on the application server.
-
Improved Performance: With an added layer placed between the backend and frontend components, we benefit from our system architecture being more maintained and optimized. In addition, this abstraction and separation of concern implemented by the BFF pattern improves performance by ensuring a reduction in backend overload and swift response to user requests, which is critical to delivering a great user experience to clients interacting with our applications.
-
Enhanced Security: By acting as a middleware between different frontend interfaces and the application server, the BFF pattern mitigates the risk of a potential system crash by abstracting and hiding sensitive server information from getting sent as part of a data response to clients making data requests.
-
Simplified Frontend Development: The construction process of modern frontend applications is optimized and improved upon as a result of dedicated BFF services engineered to listen to HTTP requests from mobile and web clients. This enables swift implementation of new features and services in modern application architectures with little to no interaction with other independent components of the backend service, such as database systems and proxy servers.
Design Patterns for BFF
Let’s take a look at the common patterns we can employ as software engineers when implementing BFF-tailored APIs:
- Single BFF for Multiple Frontends: In this implementation, one backend service is engineered to act as an intermediary between multiple frontend clients with similar interfaces submitting network requests to an application server. For example, a single BFF service can be positioned as a middleman between clients interacting with an application service from an iOS or Android device; this is possible because the user experience and formatting of data between the two interfaces are similar. The major impediment to the wide acceptance of this pattern is that it somehow shares a similarity with a traditional backend server that caters to requests from multiple clients.
- Separate BFFs for Each Frontend: Multiple BFF services are designed within this implementation to provide adequate data responses that are specific to the requirements and needs of clients, whether desktop, mobile, or third-party services. With the absence of a generic backend service that caters to network requests from different interfaces, our BFF service becomes specific to the requirements and needs of the client interfaces it is attending to. This approach optimizes our system performance while reducing the median response time for each interface interacting with our application server.
BFF Implementation with Monolithic Backends
In a monolithic architectural design, software systems comprise a client tier, an application server, and a database system. With this architecture, clients make data requests to the application server. Upon receipt of requests, the application server executes the client’s requests either by writing or reading from a database system.
A common theme of systems built with this architecture is that all requests made by users are routed to a single server body. This can eventually increase the response time and latencies of requests.
We can integrate BFF patterns into monoliths to act as a proxy interface that routes requested calls to microservices. The introduction of tailored APIs reduces response time and boosts the reliability of systems built with a monolithic or microservices architectural pattern.
Think of a social media application built on a monolithic framework; the data aggregated and presented to mobile users might need to be structured differently from that presented to web users to optimize their experiences. By incorporating tailored APIs, a BFF service acts as a proxy, redirecting HTTP calls from different client interfaces and routing them to the necessary handler functions while rendering and aggregating data from the database system to clients.
Challenges
While there are observed upsides to the incorporation of BFF services in modern software construction. There are some challenges that we can face during its implementation.
One is management issues that can be encountered when constructing multiple BFFs that will cater to network calls from clients and third-party services. It is important not to overburden our BFF services with specific tasks that are designed to be handled by traditional backend systems.
Additionally, there might be performance issues if the request volume exceeds the limit we employed in designing the BFF pattern.
Conclusion
In this article, we’ve discussed what a BFF service is and touched on how it helps in solving scalability and maintenance issues in modern internet systems. By utilizing custom APIs provided by a BFF pattern, the performance and user experience of clients interacting with our systems will be improved.