Photo by John Barkiple on Unsplash

Architecture Patterns : Backend For Frontend (BFF) Pattern

Pier-Jean Malandrino
Scub-Lab
Published in
7 min readOct 2, 2023

--

What is BFF?

The Backend for Frontend (BFF) design pattern involves creating a backend service layer specifically tailored to the requirements of a particular frontend application or a set of closely related frontends. While traditionally this approach has been contrasted with a monolithic backend serving multiple frontends, it’s worth noting that a BFF can indeed serve multiple frontends, especially when tools like GraphQL (GQL) are utilized. The key is that these frontends have similar requirements and data needs. Regardless of the number of frontends, the primary advantage of the BFF is its ability to be optimized for the specific needs and context of its consumer(s).

Here is an example of what could be a architecture including BFF pattern :

Global architecture — e.g

The applicative architecture of our Backend for Frontend (BFF) must be structured for optimal modularity and efficiency, we can propose the following :

Controllers: These are the entry points for incoming client requests. Each controller handles a specific set of endpoints, ensuring clean separation of concerns. For instance, a ProductController might handle all product-related operations for the frontends.

Services: Behind the controllers, we have service layers that perform business logic. These services coordinate a range of operations, ensuring seamless alignment between the data’s DTOs and the frontend’s requirements. Additionally, they can leverage multithreading to enhance data request performance.For instance, the ProductService might coordinate retrieving product details, calculating promotions or discounts, and interfacing with inventory management. Within this service, one could expect methods like findProductById, applyDiscountToProduct, or getProductInventoryStatus.

Data Mapping: Within the services, specialized mapping functions transform data between the domain model and the DTOs (Data Transfer Objects) that the API returns. This ensures that the frontend receives data in the most appropriate format, tailored for its needs.

Repositories: The repositories interact directly with our data sources, abstracting away the specifics of data recovery. For example, a ProductRepository might house methods for retrieving, storing, or modifying product information in the database, fetching related documents for the product or interfacing with partner APIs..

Error Handling: Throughout the architecture, standardized error handling mechanisms ensure that any issues are captured and reported back to the client in a very specific manner.

This architecture promotes separation of concerns, making the BFF flexible and maintainable. Any interface could be easily added or modified without affecting the front end.

Benefits and Trade-Offs

Avoid Coupling

Benefits

Framework Independence: A BFF can be implemented in a different technology or framework than the frontend or other BFFs, allowing developers to select the most appropriate tool for each specific frontend. This becomes especially crucial in an era with a plethora of frontend frameworks and their potentially short lifespans.

Decoupling Functional Code: Separating the backend-for-frontend from the frontend itself prevents tight coupling between functional logic and the frontend template, allowing each to evolve separately.It’s an unfavorable pattern seen in numerous frontend projects, often resulting in complex systems that are challenging to migrate.

Trade-Offs:

Resource Flexibility: Implementing BFF often requires more versatile resources. The BFF may not use the same technology stack as the frontend, necessitating developers to be skilled in multiple technologies or for teams to collaborate closely.

Potential Functional Code Leakage: If not designed carefully, BFFs can start integrating too much business logic that ideally belongs to the primary API. This can lead to challenges in maintaining consistency and can duplicate logic across multiple BFFs. On this specific note, Behavior Driven Development can be invaluable. By employing tools like Karate or Selenium, you can discern the differences in implementation. Refer to this paper for more insights :

Above is potential way to implement your BFF :

Application architecture — e.g

Network Optimization

Benefits:

Tailored Data Retrieval: By understanding exactly what the frontend requires, a BFF can ensure that only necessary data is retrieved and sent, avoiding over-fetching or under-fetching of data.

Leveraging Tools: With the BFF pattern, there’s an opportunity to use tools like GraphQL, which allows the frontend to specify the exact data structures it requires.

Trade-Offs:

Unecessary calls: Improper application of the pattern could result in unnecessary calls, particularly if developers overlook design considerations, leading to network congestion. However, it’s worth highlighting that in the absence of BFF, such a scenario would have led to I/O overload.

Data Segregation

Benefits:

Custom Data Storage: BFFs allow for data to be stored in a way that is specifically optimized for the frontend’s needs. For instance, data that supports hot configurations or client-specific settings can be stored separately.

Trade-Offs:

Risk of Data Leaks: There’s a heightened risk of exposing sensitive data if not managed appropriately, as the BFF might interact with multiple data sources or expose data that’s tailored to frontend needs.

Security Management

Benefits:

Tailored Security Protocols: BFF enables fine-tuned security implementations, supporting both authorization logic and functional segregation. This ensures data protection and only exposes necessary data to the frontend, without restriction to primary APIs.

Trade-Offs:

Reliance on API Security: While BFF handles frontend-specific security, the primary API still must implement basic security mechanisms. This means that the API exposes data without frontend-specific security but should still use basic methods like authentication.

The schema explain where authorizations could be located in the previously proposed implementation :

Application architecture security — e.g

In the case of a multi-tenant implementation, a Back for Frontend could be very useful. To learn more about multi-tenancy, read this:

Quality through Testing

Benefits:

Focused Test Scenarios: With a BFF, tests can target specific scenarios and use cases unique to each frontend. This results in more accurate and relevant test cases, ensuring that the frontend receives precisely what it expects.

Rapid Feedback Loop: Since the BFF is tailored to the frontend’s needs, automated testing can provide quicker feedback to developers. This can lead to faster iteration and more efficient debugging. Often, the adoption of unit tests is overlooked in frontend frameworks, given the lack of a dominant testing solution. This contrasts with frameworks typically favored for BFF, which tend to encourage and simplify unit test implementation.

Enhanced End-to-End Testing: The BFF allows for end-to-end tests that closely mimic the real-world user experience. By simulating frontend requests, testers can gauge the entire data flow, from the BFF to the primary backend. While one could contend that these aren’t genuine end-to-end tests, their existence, easier maintenance, and reduced likelihood of becoming flaky make them invaluable.

Trade-offs:

Duplication of Efforts: There could be overlaps between the tests for the main backend and the BFF or even frontend. This redundancy might lead to wasted resources and time if not managed correctly.

Maintenance Overhead: As the frontend evolves, so will its requirements. The BFF’s tests must be continuously updated to reflect these changes, which could increase the maintenance burden.

Risk of Over-Reliance: Teams might be tempted to overly rely on the BFF’s tests and overlook or downplay the significance of broader integration tests or tests on the main backend.

Conclusion

The BFF pattern has emerged as an innovative approach to bridge the gap between backend services and frontends, offering customization and efficiency tailored to the specific needs of each frontend or a set of closely related frontends. Its benefits, from streamlined network optimization to enhanced security protocols and focused testing scenarios, have been increasingly recognized in today’s fast-paced software development landscape. However, like any architectural pattern, it comes with its trade-offs, which necessitates a well-informed and judicious adoption strategy. By understanding its strengths and weaknesses and aligning them with project requirements, development teams can leverage the BFF pattern to achieve more responsive, maintainable, and efficient applications. As the software ecosystem continues to evolve, patterns like BFF exemplify the industry’s drive towards more modular, adaptable, and user-centric solutions.

I am the CTO and Head of an architectural unit in a digital company. I participate in the development of technological strategy, design solutions, and lead R&D projects.

Thank you for reading! If you enjoyed this article, please feel free to 👏 and help others find it. Please do not hesitate to share your thoughts in the comments section below.

Scub Lab

Thank you for being a part of our community! Before you go:

--

--

CTO & Head of Architecture at a digital firm, I drive technological strategy, design innovative solutions, & lead R&D projects.