Let's talk
  • [ Tech ]
  • [ Back for Front ]

The Backend-for-frontend Concept

Baptiste Leulliette

Published on January 9, 2025 - 2 min read

Over the past few years, the term “Backend-for-Frontend” (BFF) has been used more and more, mainly in the context of migrating technical architectures toward microservices and micro-API approaches. This type of architecture, which we develop at Kaliop, is part of a broader replatforming and composable architecture  strategy that allows organisations to modernise their systems while at the same time benefiting from greater flexibility and adaptability.

This term originates from an approach aimed at optimising communication between the various applications within a distributed system.

It involves providing tailored communication for each type of user-facing frontend, whether mobile, web, IoT, or beyond. The goal is to reduce development complexity by centralising business logic, aggregating multiple services, and delivering data in the most flexible way possible.

Backend-for-frontend: the concept, in a technology-independent manner

The idea is based on a clear separation of responsibilities: the BFF acts as the intermediate layer between the frontends and the backend side of a project, including storage layers and other external APIs.

Backend for frontend schema

Let’s consider a scenario in which a user interacts with an order management application. Without a BFF, the frontend must separately call the “Users”, “Orders”, and “Products” services. This results in multiple requests as well as manual data aggregation.

With a BFF in place, the frontend sends a single request, and the BFF is responsible for communicating with each service, assembling the responses, and returning a ready-to-use format.

This abstraction works independently of the underlying technology, whether it involves REST or GraphQL services, to name two examples among others. What changes is the way data is retrieved, aggregated, and returned.

The objective is to provide a single, optimised entry point for each type of frontend.

In a web context, let’s briefly compare why we tend to favour GraphQL over REST.

 

Are you considering modernizing your front-end/back-end architecture?

Our teams design and deploy tailored Backend-for-Frontend (BFF) architectures.

Comparison between REST and GraphQL

REST and GraphQL are two common paradigms for implementing an API interface.

While REST relies on fixed endpoints with predefined responses, GraphQL provides a single-entry point and allows HTTP clients to explicitly specify the data they want.

If we go back to the example above, in both cases an endpoint will need to be implemented to retrieve users together with their orders and associated products.

Let’s assume the REST endpoint returns this data:

{
  "user": {
    "name": "John Doe"
  },
  "orders": [
    {
      "products": [...],
      "price": "117",
    },
    {
      "products": [...],
      "price": "89"
    }
  ]
}
 

Backend for frontend : Comparaison entre REST et GraphQL

Let’s imagine that the mobile application only needs to use part of the response, in this case, the orders without the product details. In a REST context, backend over-fetching is inevitable because REST enforces use of the output model.

By contrast, GraphQL allows clients to select just the fields they request, enabling the generation of the following data:

{
  "user": {
    "name": "John Doe"
  },
  "orders": [
    {
      "price": "117",
    },
    {
      "price": "89"
    }
  ]
}
 

This approach prevents data over-fetching, reduces response time, and optimises the returned payload.

 

Practical implementation

GraphQL, created by Facebook to address the issues mentioned earlier with REST, provides a comprehensive ecosystem with a standardised front-to-back communication, as well as a wealth of tools for monitoring, caching, API federation, and more.

Implementation begins with the definition of a schema, which exposes strongly typed data models. Returning to our e-commerce example, this could be represented by the following schema:

type Product { 
id: ID! 
name: String! 
price: Float!
description: String
relatedProducts: [Product] 
}

type Query { 
getProduct(id: ID!): Product 
}
With this query, the frontend requests precisely the information it needs.
 
Once the schema is defined, the next step is to implement the business logic through “resolvers”. Resolvers receive the arguments passed in the query and fetch the necessary data to satisfy the return type defined in the schema:
const resolvers = { 
  Query: { 
    getProduct: async (_, { id }, { dataSources }) => { 
      return dataSources.productAPI.getProductById(id); // Product
    },
  },
};
So far, this is a standard backend service setup. As mentioned earlier, GraphQL, being primarily a query language, allows clients to select just the fields they need. In the example below, the associated frontend query only retrieves specific product fields :
query GetProduct($id: ID!) { 
  getProduct(id: $id) {
    id
    name
    price
  }
}
Let’s assume that the “relatedProducts” field of a product is expensive to serve. By not “selecting” this field, the query avoids unnecessary processing time, in contrast to a typical REST API.

Apollo: The Complete Ecosystem for GraphQL

At Kaliop, we use Apollo, which is one of the most robust and relevant GraphQL implementations and is widely adopted by the community.

It is worth noting that one of Apollo’s major advantages is its caching system. Several types of caching are possible:

Among its advanced uses, GraphQL is used to extend a schema with another schema to avoid a monolith effect, a technique known as “schema stitching”.

Finally, due to the “Schema first” nature of the approach, it is possible to perform “mocking”, i.e., the generation of temporary data, enabling the progressing of frontend development before the final BFF implementation even begins.

Backend-for-Frontend: an optimised approach for a modern architecture

The contributions of a BFF are undeniable, providing standardised data delivery, the ability to establish clean and optimised communication between the different layers of your project, and better separation of responsibilities.
A BFF implemented using Apollo GraphQL enables performance optimisation, both at the network level by avoiding over-fetching and thanks to the various caching options.

Enhanced communication between frontend and backend developers is often observed, thanks to the adoption of a shared schema.

Similar content