Backend For Frontend (BFF) Pattern

Jose Maria Elias
Zinklar Tech
Published in
4 min readNov 18, 2019

The BFF pattern is an architectural software pattern that improves how data is fetched between clients (a browser, a mobile app or any device connected to the Internet) and servers (any machine hosted on the cloud or anywhere else).

Why is it needed?

The goal of this pattern is to decouple the front-end apps from the back-end architecture. Let’s take a look at the following example: imagine we have 3 different apps, one for mobile, another for tablets and one desktop app. Each one has to talk with different services of your architecture, so they all need to be aware of your services.

If there is a need for restructuring your services, and you need a 4th service, there is no other way but to deploy a new version of your front-end apps to go to the new service.

So what if there is a service whose responsibility is to understand what our front-end apps need and know how to get this need from our services?

Thanks to this pattern, if a 4th service is added, we won’t need to make any changes between the front-end apps and the BFF. Obviously, we should adapt the calls to our BFF service.

This is a big improvement of our architecture because it allows us to isolate our back-end from the front-end.

Another advantage of this pattern is the reusability of the code because all the clients have the possibility to fetch data from the same BFF server, making it less complex.

But… what if all the clients talk to the BFF? You’re probably thinking that this could become complete chaos. To avoid this problem we use contracts and, to reduce the number of requests done by the clients, we support our BFF contract in GraphQL.

GraphQL is a query language for the API. You can find more info about it here.

The most important feature of GraphQL is that we can fetch all the data the client needs at a single request, helping reduce the time needed to achieve all the data necessary to carry out the request. Moreover, all this data is strongly typed so there is no implicit cast.

For example, imagine we are on the projects dashboard, where we can see all the projects we have created. If for the first call we were using REST APIs http://bff/projects for every project, the client would fetch the info of the project: http:/bff/project/1 and so on.

GraphQL allows us to do this:

With this request, the client would fetch all the info needed to show all the project data.

A query for a specific project would look something like this:

In example 2, we are asking for a specific projectId. If you’re asking yourself “what is the ! mark next to ID?”, it means that projectId cannot be null and should be an ID type.

This query to the BFF service is going to be answered by what is known as “resolvers”. There would be a resolver for the query named project and then for the customer type.

This means that if the project query resolver returns a customer_id from the project microservice, the customer resolver can fetch the data from the customer microservice with the customer_id.

So the BFF pattern + GraphQL layer is ideal for how our clients communicate with back-end services.

But…

With great power comes great responsibility!

What does it mean? You could decide to give a lot of responsibility to the BFF but this is something that should be avoided, as the domain owner should be every one of the different micro-services in their own domain. The responsibility of the BFF should only be establishing how to connect the client apps with the microservices on the same page. No more than that.

Moreover, as GraphQL is strongly typed, all the data that goes through it will be cast to what is written on the contract, so if a request of tons of megabytes is sent out, this will imply a huge impact on performance due to the type checking.

--

--