What is a BFF? And how to build one?
Who wants to build a monolith nowadays? Microservices are the way to go! But that’s no cheap alternative. It introduces all sorts of complexity. For example: Assume having several user-interface agnostic microservices, how “chatty” will your SPA or mobile app become?
General-purpose APIs might require consumers of APIs to aggregate and filter the responses of various endpoints to render something useful to the end-user.
And how will an architecture of multiple micro-frontends connected to a series of microservices impact maintenance? The promise of microservices is that they will make your application more agile. Create a new microservice as you please and tear one down when need be. But how will this impact the front end?
So, to solve that problem, yet another pattern occurred: The Backend For Frontend. The concept is what you might expect: One backend for every frontend that will act as an interface between a frontend app (SPA/Mobile) and the domain services. It’s an API that queries downstream services and transforms the response(s) to one single response formatted specifically for one specific front end. Schematically, BFFs in a microservice landscape might look somewhat like this:

The BFF concept was first introduced at SoundCloud.
BFF, authentication, and the cookie-less era
You might wonder how that’s relevant to this article. But especially the cookie-less era makes the BFF pattern a little more complex than you would first guess from the picture above.
In many cases, downstream services require authentication. Usually, (access) token-based. The BFF needs to include these tokens in the requests that are forwarded downstream.
It’s a common practice to store access_tokens in the SPA. It includes it in the requests and, a presto, the API knows who’s executing the request. But there is going to be a problem with this approach in general. When a token expires (typically after one hour), SPAs usually, silently renew them. This mechanism is based on third-party cookies and those are not working anymore soon. As a result, silent renews will not work anymore in 2024.
Considering this, and the fact that the BFF requires the user’s access_token anyways makes authenticating to the SPA is a strange thing to do. With a BFF, the SPA is not supposed to communicate with a downstream service directly and because they’ll require authentication, a BFF will always need to include an access_token in requests downstream. So, from that perspective, it makes more sense to have the end-user authenticate to the BFF only. This eliminates the need to renew the token via the SPA (and the need to have tokens in the SPA at all).
This diagram illustrates what the authentication process with a BFF and some microservices look like:

To get this to work, the BFF and the SPA must be hosted on the same URL. That way, when the SPA initiates an HTTP request to the BFF, the HTTP requests will include cookies. The BFF needs those to get the user context (the access_token) and to forward it downstream.
So, how to implement it?
A BFF is a part of the front end. It is an API that reduces the number of API requests to downstream services and reduces the amount of data that travels over the wire between the front end to the BFF. It does that by translating and forwarding API requests to one or more generic APIs. It aggregates and transforms the response into responses that contain only what the front end needs.
This is still a pretty broad definition. That’s annoying. Because how will you implement it? To make matters more complex, Cam Jackson makes it even more complex:

So, by this definition, several approaches qualify. They range from full-fledged APIs that have dedicated storage to third-party software that forwards requests and transforms the responses if need be.
Option 1.) Duende
You don’t have to do it yourself. Several projects offer a free-to-use, off-the-shelf solution. For example, from the maintainers of IdentityServer, there’s a solution called Duende: https://docs.duendesoftware.com/identityserver/v5/bff/ (implementation samples here: https://docs.duendesoftware.com/identityserver/v5/samples/bff/)
By including Duende in a project, it will start working as a BFF. It implements the authentication mechanism, and it can be configured to forward requests to downstream APIs.
Option 2.) OidcProxy.Net
Duende is a great option for a BFF, but it has one downside: the license. Duende is free in some cases. To purchase it, Duende will make a custom quote for your organization. In some cases this results in a procurement-nightmare.
If you are looking for a similar approach, you might want to check out the OidcProxy.Net project:
Check out the GitHub project here:
Option 3.) Build it yourself!
Considering the non-generic nature of a BFF, it makes sense to build it yourself. You’ll need to do the following:
- Create an API project
- Implement authentication. Use the OpenId connect authorization code flow (with PKCE) and store the access token in a secure cookie.
- Create API endpoints and grab the token from the cookie. Use it to invoke endpoints of the services you want to use.
- Transform the response if need be.
- Create a SPA and host it on the same site/project
- Have the SPA post to the API endpoints you created earlier.
- That’s it…
Summary
Communication between microservices and micro-frontends might not be too efficient. A microservice has a general-purpose API (if it has an API at all), so a front end might need to use multiple microservices to get things done and filter the information it needs to display from the responses. As a result, the front end gets chatty.
Also, when services get smaller, you’ll have more services to get things done. Invoking all of them in several front ends might not be desirable. It makes maintenance harder (versioning).
To solve these problems, at SoundCloud, they introduced an extra layer in their architecture. They would ship an API as a part of their front end. It acts as an interface between the front end and the services downstream. It aggregates or/and filters the responses into an efficient response.
This concept is called a Backend For Frontend.






