Why big companies and rapidly growing startups need Back-end for Front-end

Ksenia Lvova
Blue Harvest Tech Blog
6 min readFeb 23, 2020

Imagine this, you’re a front-end developer working in one of the product teams and you need to add a new feature to the product. Typically, both the front- and the back-end teams need to discuss, write code, make pull-requests and repeat this time-consuming cycle. All for a relatively small feature. Does that sound familiar to you?

Motivation

A typical API architecture of an enterprise application implies a lot of microservices. Most often these systems are designed as direct API calls between the front-end and the back-end. With the current number of different platforms and a variety of user interfaces, API’s and user-interfaces are rapidly expanding when business keeps expanding. But what happens if you don’t have an active back-end team? Or, what happens if you have just one back-end team responsible for delivering API’s for multiple user-interfaces and platforms? Obviously, a lack of developers leads to troubles with creating and supporting many endpoints for each platform.

These problems (which exist on an architectural level) have a negative effect on the “time to market” and cause unnecessary tensions between product-owners and development teams, whether it’s front- or back-end. For instance, a few product teams should update their APIs during one sprint and changes are affecting the same data. That means teamwork in an agile atmosphere needs to be planned upfront to optimize collaboration. A major drawback of having a progressively increasing number of API’s is that it’s very hard to control on both sides (both front-end and back-end). Each change in the design refers to an API change.

All of these reasons slow down the development process and increase the cost of maintaining system stability as they involve a lot of development resources. Further increase of development teams for supporting and developing API features gradually causes troubles with orchestration, routing, etc. The below illustration shows us that API design (when it has a one-on-one relation with the front-end) should be improved

Setting up the scene of general API
Setting up the scene of general API

Time to think about solutions

There are a set of requirements we need to consider. Back-end should only be responsible for data models, data storage and relations between entities and data models. Back-end should not worry about any changes within the front-end.

Also, one of possible use-cases might be having a framework-agnostic frontend in case of willingness to swap one framework to another, for instance, moving from VueJS to ReactJS easily. Frontend teams should be responsible for UI including cases when the FE team solves by its own various model associations that are used for the specific client application. Thus, we understood that creating custom endpoints or methods per UI (for instance /transactions/list-for-desktop and /transactions/list-for-mobile) forces us to have:

  • a predefined list of endpoints
  • the overall design of the API becomes blurry

This approach is moving away from domain-driven design to the domain plus consumer context-driven design.

We came up with a Backend for Frontend(BFF) approach that fits the best current technical request. BFF design pattern was intended to keep one interface for all APIs and acts as a transformation layer between front-end and API. It’s a task to aggregate data from downstream services and presents it in a way that is tailored for particular user experience. BFF doesn’t implement business or application logic, but only data transformation and aggregation. From the development point of view, BFF is mostly the request of the FE team because the FE knows what endpoints, required data, transformations should be used on the frontend. This will allow them to implement features independently from the API team and speed up their development process. So if the API team implements a new feature one of the UI team can quickly pick it up and start using while the mobile team might catch up. BFF layer is giving freedom to FE teams to build FE quickly and independently with simple data structures, well-described errors and providing powerful logging and error handling mechanisms. It reduces unnecessary tensions between FE and BE teams for benefits for both of them.

Basic concept of BFF
The basic concept of BFF

How many BFFS?

Option 1. One BFF for each UX(desktop vs mobile). Similar clients might share the same BFF(iPhone and Android clients) since their UX might be identical

Option 2. One BFF per team. This will allow the teams to choose their own stack and work independently

Each BFF layer implies one entry point API and a tool that resolves the response for this API. For example, GraphQL seems to be a better solution on the market.

BFF with GraphQL

GraphQL is a communication protocol for implementing BFF which can be used as a request format from FE to BFF to replace multiple endpoints and give more power to FE. GraphQL gives the client(FE) the ability to fetch all required data in a single request and filter the results. BFF GraphQL server as a tool provides “routing” functionality of request to resolvers and sends back the response to FE with transformed results.

Let’s take a look at the presentation of one of the BFF layers more closely using GraphQL.

BFF with GraphQL
BFF with GraphQL

How does it work?

  • The GraphQL client sends the request to the GraphQL Server
  • The server parses and validates the query against the schema
  • Each field is mapped to a resolver which is a function responsible for fetching the data
  • The data can be fetched from the remote service, a database or any other source

Ask for what you need:

GET/POST Request:

{ accounts { id, currency, balance } }

Response payload:

{ “data”: { “accounts”: [{ “id”: “qwey182392739127”, “currency”: “EUR”, “balance”: “12312.4534” }, { “id”: “qwelqwiue9q7we9”, “currency”: “USD”, “balance”: “3.000000” }] } }

BFF Benefits:

  • Single Entry Point for FE
  • Ability to build very flexible API and transparent to the FE
  • Good tooling support and libraries (Apollo GraphQL, GraphQL Playground, Graphiql, GraphQL Voyager)
  • Unlimited querying capabilities(e.g. filtering expanded elements)
  • Unified API / protocols for FE
  • Reduce API calls number from FE
  • Reduce traffic amount
  • Single point to collect data-flow logs

BFF Drawbacks:

  • Not suitable for some situations (e.g. streaming)

How to eliminate drawbacks:

  • Making BFF the responsibility of a FE team
  • Using a strict data schema to avoid data structures inconsistency
  • Using GraphQL approach for request unification and reducing the number of requests from FE to BFF
  • Considering not to use BFF for unsuitable operations: streaming, sockets, uploads/downloads

Wrap up

Takeaway 1. The API should be designed for the need of the client

Takeaway 2. Different clients need different APIs

Takeaway 3. GraphQL allows you to put the client in charge

Links and Further Reading(Watching):

  1. GraphQL server for Node.js BFF implementation: https://www.apollographql.com/
  2. A good example for Flickr photostream querying: https://github.com/ollyd/flapi-bff
  3. Creator of BFF https://samnewman.io/patterns/architectural/bff/
  4. Implementation BFF in SoundCloud https://www.thoughtworks.com/insights/blog/bff-soundcloud

Thanks to Andrew Kuznetsov for help in researching and preparing this article.

--

--