This article is a summary of my presentation at the O’Reilly Software Architecture Conference in London.
Maintaining an API gateway these days generally involves handling different types of user-facing apps such as web, mobile (of different platforms), and IoT devices. The Backend for Frontend (BFF) pattern specifically addresses this aspect of software solutions.
At Intellectual Apps, we build software solutions, and in creating solutions for our clients we frequently get to build web and mobile apps within a single solution. This often means that we have a single API gateway for all the apps to communicate through. Over numerous clients/projects/products we started to notice a lot of repetition in the modules we built into software solutions, so naturally, we sort to find a way we could share functionality across solutions in an easy way and this lead us to start experimenting with microservices.
In building microservices-based solutions, as the name suggests, one ends up having several independent services working together as part of a single solution. This posed a specific challenge for us as we now had to make the user-facing apps do a lot more work in composing data from numerous services. So we took a step back and after some brainstorming, we realized that we had several other problems which presented themselves in two forms:
- Having all apps communicate through a single API gateway.Apps communicating through a single API gateway
- Having apps communicate with multiple services.Apps communicating directly with microservices
These scenarios created the following specific challenges for us:
Having all apps communicate through a single API gateway.
Given that the data consumption patterns of mobile apps are not the same as web apps, having all the apps share a single API gateway meant that the mobile apps often got more data than necessary when calling the same endpoints being used by the web application. For instance, when returning data to show the details of an item, the web app has room to show way more details than a mobile app can. So when the mobile app calls the same endpoint it simply gets more data that it can possibly display on a small screen which means a lot of the data never gets displayed immediately.
With all apps communicating through a single API gateway, the codebase got bloated. Many at times this was due to the fact that checks were put in place at the API gateway level to determine which app was to make the call just so that app-specific things could be done.
Having apps communicate with multiple services.
The major challenge with this approach is the extra processing that mobile apps had to do in order to compose data coming from multiple independent services in addition to the numerous network calls that have to be made. The immediate effect of this is the drain on battery life.
Enter the BFF
After conducting some research we came across the Backend for Frontend pattern and the motivation for us considering this was to enable us to operate in a more agile fashion. The approach was popularized by Sam Newman, the author of Building Microservices. Sam Newman talks about his experience working on a SoundCloud project which faced challenges similar to ours and how he and the team there applied this approach to address the challenges.
We adopted the BFF approach and applied it to our projects and this made our architecture look as follows:
Apps communicating via BFFs
The BFF pattern is a technique where a dedicated layer serves a specific front-end platform. It can easily be seen from the diagram above that each platform gets a specific layer that performs the following functions:
- Data composition.
- Some front-end specific logic.
Having BFFs perform the functions listed above means that:
- Mobile apps won’t have to make multiple network calls.
- Mobile apps do less work on data as data composition takes place in the BFF.
- Each platform gets the right data needed from each call.
- Codebase for each BFF is specific to a platform therefore getting rid of a bloated codebase.
When to use the BFF pattern
If one or more of the following is true in your current architecture then the BFF pattern may be something to consider:
- You have web, mobile and IOT apps talking to multiple services.
- You have web, mobile and IOT apps sharing a single API gateway.
- You are migrating to microservices.
- You have organisations outside yours consuming your APIs.
A Little More
Typically the front-end team should maintain the BFFs as these layers are technically extensions of the apps they work on. Doing this will let your front-end team iterate faster as they won’t have to communicate with another team, supposing the BFF is maintained by the back-end team.
It may be argued that there will be duplication of code across BFFs, yes, this holds true but the trade-off here is having bloated code in a single API gateway. We even go to the point of having separate BFFs for Android and iOS platforms as this lets us focus specifically on one platform.
It also goes without saying that with the BFF approach, there will be more codebases to maintain.
That’s it and I hope you find this article useful, and consider using this pattern as we do at Intellectual Apps so you could respond faster to client and user requirements.