Briefly
Gateway and Backend-for-Frontend (BFF) are design patterns for developing web applications. Both patterns are used to provide access to different APIs through a single contract. A contract is everything that allows two network nodes to communicate: the architecture of network connection, the set of network protocols, the set of addresses and ports to access data, the rules for forming requests from clients, and the mechanism for preparing and sending responses from the server.
How to Understand
A modern web application consists of an interface that the user interacts with and a backend that the user does not see. The backend can be structured in different ways, depending on the task. The backend of large web applications is usually quite complex.
Typically, the backend is a combination of different programs (microservices) or one large program (monolith). The microservices approach is increasingly used in modern web development, which you can read about in the article “Microservices”. The problem with such a complex backend lies in the fact that each microservice provides a unique API. The frontend has to work with each microservice separately and remember each one's API. This is inconvenient, creates a tight coupling between the frontend and backend, and requires extensive knowledge of the backend's internal structure. The solution to this problem is to create a single unified interface that will, in turn, interact with all microservices.

One of the first such solutions was Gateway, which is generally a proxy server providing a single point of access to data through a specific API (Application Programmable Interface — API), forwarding data from the frontend to the appropriate microservice and back. The appearance of the user application may change, business logic may change, the client application may change, and the contract may also change, but this does not affect the other APIs. The Gateway forwards client requests to other APIs, taking into account differences in contracts, thus reducing the coupling of the backend and frontend in a web application. Typically, on the Gateway side, frequent requests can be cached, and simple business logic can be implemented to control the set of forwarded data between the client and the external API.

The operation of Backend-for-Frontend, which is a development of the single point idea, is similar to Gateway in ensuring a single contract and controlling the data set. BFF necessarily includes Gateway, which has the following requirements:
- Common templates on the client and server (for example, JSX).
- High response speed under load.
- A single language on the client and intermediate BFF server.

Common templates are very important as they significantly speed up development and simplify support for both the client part of the application and the BFF server application. Given that the language should also be unified, this allows for code reuse on the client and server. High response speed is achieved not only by caching frequent requests but also through data pre-processing for client requests.
BFF can be used not only for accessing various APIs. For example, the BFF pattern fits perfectly into the architecture of building a web application in which microservices operate on the server side. You can read about them in the article “Microservices”.
How to Start
If JavaScript is used as a development language, it is evident that you need to ensure code execution. Most likely, you will use Node.js, but there are alternatives: Deno or GraalVM. Node.js is perfect for a large number of input/output operations, but not for calculations. For BFF, it is an excellent choice.
The next step is to choose an architecture. This stage is very important because the choice of architecture determines future support and development of the application.
The concept of layers fits perfectly for BFF. In this concept, the user interface (in our case, the API that the client addresses) is separated from business logic and data. Server applications are usually built on layers and the relationships between them. There are several approaches to implementing layers.
Three-tier architecture is historically one of the first approaches that is built upon the collaboration of three layers: the client layer, the business logic layer, and the data layer. The lowest layer is the data layer. It interacts with the business logic layer, which in turn interacts with the client layer. In three-tier architecture, the client layer is insulated from the data layer.

The problems with this approach are obvious. The entire application is built in connection with the data. For example, the structure in the database will completely define all upper layers, which is fundamentally incorrect. This does not allow for the necessary level of abstraction. There will be problems if some external API or method of obtaining data from a microservice changes. Developing and maintaining such an application will be extremely challenging.
Domain-Driven Design (DDD) is a more modern approach, where the application is divided into four layers: user interface (client), business logic, domain, infrastructure. In this approach, the bottom layer is the infrastructure layer, above which is the domain layer (which defines all entities necessary for the operation of the business logic layer within the domain area).

This approach is not bad, but it’s too heavy for BFF. Often, product requirements are such that defining the domain and main business logic should lie with the backend. The BFF’s task is to be a convenient and lightweight layer between the frontend and backend.
It is important to note that sometimes the infrastructure must be visible from the business logic level, which leads to a problem known as leaky abstraction. This problem is related to the need to isolate layers for proper future support and development of the architecture. Only the upper and lower layers can know something about the current one, but not the others.
Clean architecture is an even more modern approach that uses the same four layers as in DDD, but differently. The infrastructure layer is raised to the level of the user interface. This allows avoiding leakages of abstraction. The domain becomes the center of the application. Clean architecture is used in modern BFF applications.

As a framework, Express is often chosen in conjunction with Nest.js. Certainly, the design of a specific application depends on the business task and the domain area of the web application. You can read about several successful practices using BFF in the following articles:
- Backend for Frontend, or How Yandex.Market Creates APIs without Hacks.
- The Architecture of Modern Corporate Node.js Applications.
- Backend-for-Frontend: When a Simple API Is Not Enough.
There are projects with small BFFs, for example, this one:
- Code of the project for the article “JWT Architecture for Modern Apps”