Some common design patterns for the front end, BFF and back end

At the beginning of this article, my colleagues in our group recently implemented a set of Redux on the client, redesigning the functions of a certain business domain. Both iOS and Android follow this set of rules, namely, Redux. Why do you need a client to implement a set of Redux? The business logic of the commodity module is very responsible, and there is a lot of basic commodity information, such as multi-specification, multi-unit, price, inventory and other information, as well as corresponding store and online store models, as well as various industry ability switch control. The early implementation of Rx role, resulting in complex code logic and chaotic data flow. The architecture design and code maintenance are not very elegant. In addition, there is a big business adjustment recently, and the students in the middle stage reconstructed the business by Redux + one-way data flow.

IOS and Android declare DTO Model respectively, and then parse the data to generate the data required by the client. In this way, “repeated” behavior often occurs, so we simply use TS + script. The ability of the gateway data model to automatically generate iOS and Android models has been removed. However, when discussing the framework design, people refer to React Redux, Flutter Fish Redux, Vuex, etc., and talk about one-way data flow and two-way data flow. However, some students’ understanding is wrong. So the first part of this paper “error correction” part is to clarify the front several key concepts.

The rest is explained in logical order: microfront-end -> BFF/ gateway -> microservices.

First, correct the wrong questions

1. Is Vue a two-way data stream?

If the answer is “yes”, then you probably don’t understand the concepts of “two-way data flow” and “two-way binding”. In fact, the two are not exactly the same thing, one-way data flow can also achieve two-way binding.

In fact, if you look closely at the official documentation of Vue, it is stated that Vue is actually a one-way Data Flow. Here’s an official quote

To be clear, when we say data flow, we mean data flow between components. All props in Vue have a one-way downlink binding between their parent props: updates from the parent props flow back down to the child component, but not the other way around. This prevents accidental changes in the state of the parent component from the child component, making your application data flow difficult to understand.

In addition, every time the parent component changes, all props in the child component will be refreshed to the latest value, which means you should not modify prop in the child component, and if you do, the browser will issue a warning in the console. Vue and React props

React is MVVM?

Instead of answering that question directly, let’s talk about a couple of concepts, and once we’re clear about those concepts, the answer to that question will be clear.

2.1 Differences between One-way binding and bidirectional binding?

Binder is a must when it comes to MVVM. One-way binding and bidirectional binding.

Vue supports one-way binding and bidirectional binding. A one-way binding is an association between a Model and a View, such as v-bind. Two-way binding means that updates to the Model are synchronized to the View, and changes to the View are automatically synchronized to the Model, such as the V-Model.

V-model is actually syntax sugar, because Vue is a tamplate, so after webpack AST parsing, tamplate will become render, v-model will become V-bind and V-ON

One-way binding + Auto Event Binding is a simple way to achieve the effect of two-way binding. The following

In fact, a look at the source code will find (Vue3 Proxy), one-way binding and two-way binding difference is that two-way binding to the data change part of the operation, by the framework of the internal implementation, the caller does not need to perceive.

2.2 Redux

A typical flowchart for using React Redux is as follows

If we hide the implementation of action and Dispatcher inside the framework, the diagram can be simplified as

If further, we hide the mechanism of mutual manual notification, which can be simplified as

If you look closely, is it MVVM? The answer to that question is obvious. React is not MVVM.

3. Is Vue MVVM

The official states that “it is inspired by MVVM, although it does not follow MVVM ideas exactly. So when we Debug, we often see that changes to the VM “Model” will trigger an update to the View. This is reflected in v-bind. Changes to the View, even if they are synchronized to the Model, are reflected in the V-Model. But Vue breaks the MVVM specification by providing the Ref attribute, which allows you to use the Ref to retrieve the Dom and manipulate some of its styles or attributes directly

4. Usage scenarios of one-way binding and bidirectional binding

Why did Vue remove.sync and Angular add < for one-way binding?

As applications get bigger and bigger, two-way data flows can bring unexpected results that complicate debugging, debugging, and testing.

So Both Vue and Angular realized this and removed.sync in favor of one-way binding.

Talk about the problem head-on:

The benefits of one-way binding, which brings one-way data flow, are that all state changes can be recorded and tracked. State changes must be notified by manual invocation and traced back to the source, without “black box operation”. At the same time, the component data only has a unique entrance and exit, making the program more intuitive and easier to understand, conducive to the maintainability of the application. The disadvantage is that the amount of code increases and the flow of data becomes longer for the same requirements. At the same time, due to strict requirements for independent management of application state (single global store), it is particularly tedious to deal with scenarios with more local states (such as “rich form” applications with more user input and interaction).

The advantage of bidirectional binding is that it simplifies a lot of business-independent code in a scenario where forms interact a lot. The disadvantage is that due to the “black box operation”, local state changes cannot be traced, and too many potential behaviors increase the difficulty of debugging when errors occur. At the same time, as component data changes from more than one source of entry becomes possible, programmers are uneven, the written code is easy to make the direction of data flow disorder, the quality of the entire application is not controllable.

Conclusion: One-way binding and two-way binding are basically complementary in function, so we can use the right method in the right scenario. For example, in UI controls (usually form-like operations), data can be bound in a bi-directional manner; Other scenarios use one-way binding

Two, micro front end

Vue, React, one-way data flow, and two-way data flow mentioned above are all organized and designed for a single application. However, there will be some problems when the application is very large. Which brings us to today’s theme, “the micro front end.”

As you all know on the client side, we’ve been using componentization and modularization to split code and logic for a long time. So you can say what is a component and what is a module?

Component is to extract the repeated code to merge into a component, component emphasizes reuse, located at the bottom of the system, other functions are dependent on components, strong independence

Module refers to the code belonging to the same function/business is isolated into independent modules, which can run independently. It is divided into different modules based on pages and functions, and located in the business architecture layer.

These concepts are also true in the front end. For example, those who have written Vue and React know that a page needs to be split into components. A large page consists of multiple UI sub-components. Modules are the same, the front end uses self-executing functions (IIFE) for modularity, mature CommonJS, AMD, CMD, UMD specifications, etc. For example, the iOS side uses modularity to realize the separation of business domains such as goods, inventory and billing, and also realizes basic capability modules such as routing library and network library. The front end is more about modularity for namespace and code reuse

In fact, it can be seen that the front end, the client implementation of modular, componentization of the goal is the idea of divide and conquer, more is to stand in the code level of separation, organization management. However, as front-end engineering becomes more and more heavy, it is difficult for traditional front-end architecture to follow the idea of “agile”.

1. What is a micro front end

People who care about technology hear microfrontend and immediately think of microservices. Microservices are a variant of service-oriented architecture that designs applications as a series of loosely coupled, fine-grained services organized by lightweight communication protocols. Older and heavier front-end engineering faced the same problem, and it was natural to borrow the idea of microservices from the front end.

To get back to business, micro-frontends are a microservices-like architecture that applies the concepts of microservices to the browser side, transforming Web applications from single monolithic applications into aggregations of small front-end applications. Each front-end application can also run, develop and deploy independently. A microfront-end is not a simple front-end framework or tool, but a set of architecture.

Characteristics of 2.

2.1 Technology independent

Throw two scenarios and think about it:

  • You’re new to a company, and your boss throws you a five-year-old project that you need to iterate on and add features to.
  • When you start a new project, your boss, who is used to seeing the ups and downs of technology at the front end, only gives you one architectural requirement: “How do you make sure that this technical solution is still viable in 3 to 5 years and will not become another legacy project in 3 to 5 years?”

For the first scene we thought, ok, I’ll just use React/Vue. They’re just UI libraries anyway, so give me a Dom node and I’ll render it as I want. But have you ever considered that this is just the view implementation floating on the surface, the engineering infrastructure sinking underneath? How do I package the React component and integrate it into the original ES5 code? Or how do I get Webpack and Grunt to coexist in a friendly way to produce a Bundle that meets expectations?

Second scenario, how do you ensure that the technology stack remains viable for 3-5 years? Don’t cross frameworks. Even React 15 and 16 are not compatible. Hooks cannot be used in Class Component. There is also the packaging scheme, now it is good to default Webpack, how about the Webpack version upgrade, do you follow up every time? Don’t forget Babel, less, typescript, etc.? How many people can guarantee that their project will still be running after a year with all dependencies updated to the latest, let alone 3 years?

The reason for these two scenarios is that if we look at the companies in the industry that have made noise about “micro front ends”, we will find that adopt micro front ends are basically ToB software services, and no ToC companies have micro front ends (some are also internal middle and back end systems). Why is this? Simple, because few ToC software will survive more than three years. For ToB applications, 3 to 5 years is too common. Go to see ali cloud earliest those products console, go to see those telecom software, banking software, which is not 10 years + life? I won’t say much about how painful it is to upgrade enterprise software. So the core appeal of most enterprise applications is how do I make sure my legacy code migrates smoothly, and how do I make sure I still have access to the hot technology stack years from now?

How to continue the legacy project is our initial appeal to the micro front end. Many development may not feel deep, after all, those who make millions, a year’s worth of projects either die, or is thrown to the outsourcing team maintenance, but want to know, to do a lot of small and medium-sized enterprises in the field of ToB, such a system might be their living, can not say it is, they can’t bear such a high cost of trial and error.

Even for new business, each technical team should be able to choose the appropriate technology stack according to the technical reserve of its own team members and business characteristics, without paying special attention to the situation of other teams. That is, team A can use React, team B can use Vue, and team C can even use Angular to implement it.

2.2 Simple, loosely coupled code base

Microfront-end architecture is much smaller and easier to develop and maintain than a whole front-end engineering. In addition, it is more important to avoid the increase in complexity caused by unreasonable implicit coupling between modules. Well-defined application boundaries reduce the likelihood of accidental coupling, increase the cost of logical coupling between sub-applications, and force developers to be clear about the flow of data and events through the application

2.3 Incremental Upgrade

The ideal code would naturally be modular, dependent, easy to extend, easy to maintain… In practice, however, for a variety of reasons:

  • History project, family code
  • Deliver pressure, then fast
  • Close to ripe, then stability……

There is always less than ideal code:

  • Backward technology stack, and even forced to mix multiple technology stack
  • Coupling chaos, dare not move, pull a restless body
  • Incomplete reconstruction, reconstruction – rotten tail, change posture reconstruction – rotten tail again…

The biggest problem with a complete refactoring of this code is that it’s hard to have the resources to do it all at once, ensuring a smooth transition in the middle while still delivering new features:

So, in order to implement progressive refactoring, we need an incremental upgrade capability that allows the old code to coexist with the new, and then gradually transform the old code until the entire refactoring is complete

This incremental upgrade capability means that we can make low-risk partial replacements of product features, including upgrade dependencies, replacement architectures, UI reworks, and so on. On the other hand, it also brings flexibility in technology selection, which is conducive to experimental trial and error of new technologies and new interaction modes

2.4 Independent Deployment

The ability to deploy independently is critical in a microfront-end architecture, narrowing the scope of change and thus reducing the associated risk

Therefore, each microfront should have its own continuous delivery pipeline (including build, test, and deploy to production) and be able to be deployed independently without much consideration for the current state of other code bases and delivery pipelines:

If Biz A, B and C have three systems, the three can be deployed independently, and finally the main system will integrate and release the application. It’s more independent and flexible. If you think about A single application in the past, such as A complex business application, it would be very likely that the entire application would fail when B was built without passing Lint, which would not only waste time building A, but also make the entire application build serial and inefficient.

2.5 Team Autonomy

In addition to code and release cycle on the decoupling, micro front also helps to form an independent team, by different team is responsible for a piece of their independent functions of products, according to the division Biz to best, because the code are independent, so the front-end based on Biz business team, can design thinking, provide a more reasonable interface and ability. Even more basic capabilities can be abstracted, providing more complete capabilities in line with business thinking, that is, more autonomy for the team.

3 How to Implement it

The micro front end mainly adopts the combined application routing scheme. The core idea of the scheme is “master and slave” (are those who have played Jenkins familiar with it?), that is, it includes a base “MainApp” application and several micro applications (MircroApp). Mainly be responsible for the application for registration, route map, such as the issuance of the news, and the application is the front end of the project independently, these projects are not limited to the specific technology (React, Vue, presents, Jquery), etc., each application registered to the base, run by base, even without the base, these applications can access alone, as follows:

The problems that a microapplication framework needs to solve are:

  • Route switchover distribution problem

    The base application, as a micro-front-end, is the entrance of the whole application and is responsible for carrying the display of the current micro-application and forwarding of other routing micro-applications. The display of the current micro-application is generally composed of the following steps:

    1. As a SPA base application, it is a set of pure front-end projects. In order to display the page of micro-application, iframe should be adopted and the page content of micro-application should be pulled first, which requires the remote pull mechanism.
    2. The remote pull mechanism usually uses the FETCH API to fetch the HTML content of the micro-application first, then extracts the JavaScript and CSS of the micro-application through parsing, and runs the JavaScript using eval method. And append CSS and HTML content to the display area reserved for the micro-application in the base application. When the micro-application switches, unload these contents synchronously, which constitutes the display process of the current application.
    3. Of course, this process will involve CSS style pollution and JavaScript pollution of global objects, which will be discussed later. At present, there are ready-made libraries to implement the process of remote pull mechanism, you can refer to import-HTML-entry and system.js.

    As for route distribution, the base SPA application developed by VUe-Router is taken as an example, which is mainly the following process:

    1. When the browser’s path changes, vue-Router listens for a Hashchange or popState event to determine the timing of a route switch.
    2. The router of the base is the first to receive this change. By querying the registration information, it can obtain the route forwarded to the micro-application. After some logic processing, it uses the modified Hash method or pushState method to route the information to the micro-application. Microapplications can manually listen for hashchange or popState event reception, or use react-Router or vue-Router to take over the route. The logic is then controlled by the microapplication itself.
  • Isolation of master and micro applications

    Application isolation problems are mainly divided into main application and micro application, JavaScript execution environment isolation between micro application and micro application, CSS style isolation, let’s talk about CSS isolation first.

    CSS isolation: When the main application and micro-application render on the same screen, some styles may pollute each other. If you want to completely isolate CSS pollution, you can use CSS Module or namespace to give each micro-application Module a specific prefix to ensure that it will not interfere with each other. You can use postCSS plug-in of Webpack. Add specific prefixes at packaging time.

    CSS isolation between microapplications is very simple, marking all the link and style content of the application each time the application loads. After the application is uninstalled, synchronize the corresponding Link and style on the uninstallation page.

    JavaScript isolation: Whenever a microapplication JavaScript is loaded and run, its core is actually the modification of the global object Window and some global events. For example, jQuery will mount a window.$object on the Window after it is run. To do this, you need to load and unload each microapplication while eliminating this conflict and impact as much as possible, most commonly by using a SandBox mechanism.

    The core of the sandbox mechanism is to keep the local JavaScript runtime’s access to and modification of external objects under control, meaning that no matter what happens inside, it doesn’t affect external objects. The VM module is usually used on the Node.js side, but for the browser, you need to sandbox the browser side with the with keyword and the window.proxy object.

  • Communication problems

    There are many ways to communicate between applications, but of course, communication between separate microapplications is essentially dependent on intermediaries or global objects. Therefore, the communication mechanism of message subscription (PUB/SUB) mode is very suitable. In the base application, the Event center is defined, and each micro-application registers the Event separately. When the Event is triggered, the Event center distributes the Event uniformly, which constitutes the basic communication mechanism.

At present open source many micro front-end frameworks, such as Qiankun, interested can go to see the source code

4. Check whether to use a micro front end

Why do a micro front end? Or what problem does the micro front end solve? That answers the question of whether a micro front end is needed. Single-spa, the ancestor of the microfront, initially solved the problem of using a new technology stack in an old project. At the present stage, another major problem to be solved by the micro front end announced by Ant Financial Qiankun is the difficulty in maintenance and collaborative development of boulder project. If the project is facing both of these problems, I think the micro front end is a good place to try. What do you think?

3. Thoughts on constructing BFF based on GraphQL in microservice platform

1. Large front-end architecture evolution

Let’s tell a story

1. V1

Suppose that in early 2011, an e-commerce company completed the separation of single applications and the back-end services had been SOA-BASED. At this time, the application form was only Web. The V1 architecture diagram is as follows:

2. V2

Time came to the beginning of 2012, domestic blowing a gust of wireless application wind, each big factory began their own wireless application development. To address this requirement, the architecture was adjusted to V2, as shown below

There are some problems with this architecture:

  • Wireless APPS and internal microservices are strongly coupled, and changes on either side may affect the other

  • Wireless apps need to know the internal service details

  • The wireless App side needs to do a lot of aggregation tailoring and adaptation logic

    Aggregation: A single page may require several back-end apis to be combined simultaneously, such as the data required for a product detail page, which cannot be done in one call

    Tailoring: The basic services provided by the back-end are universal, and the Payload returned by the App is large and has too many fields. The App needs to tailor the fields according to the device and service requirements. Is the user’s client Android or iOS, large or small screen, and version? For example, which industry does the business belong to, what is the product form, what scenario is the function put in, who is the user group for and so on. These factors all lead to differences in the logic of the end – oriented functionality. In the context of microservices and domain-driven design (which is not the focus of this article), each service provides the basic functions of the current Domain, such as the commodity Domain, which provides the function of adding, querying and deleting goods, list function and detail page function.

    But in the case of the item detail page, the data requires the ability to invoke the item domain, the inventory domain, and the order domain. The client needs to do a lot of network interface processing and data processing.

    Adaptation: Some common adaptation is format conversion. For example, some back-end services are older and provide SOAP/XML data but do not support JSON. In this case, some adaptation code is required

  • As the usage types increase (iOS Phone/Pad, Android Phone/Pad, Hybrid, applets), the development of aggregation tailoring and adaptation logic can cause a lot of repetitive work on the device side

  • Front-end such as iOS, Android, small program, H5 biz all need business data. The earliest design was a straight out back-end interface. This design causes a problem because biz1 is iteratively released, resulting in the implementation of the back-end change interface. Another requirement of Biz2 will cause the server side to change the design implementation, resulting in a business-oriented interface. Are the underlying services developed for business interfaces at all? This is a departure from domain-driven design

In this context, the BFF (Backend For Frontend) layer was born. Each field provides basic data model, and each biz has its own BFF layer. Query on demand (for example, commodity basic data is 200, but the small program list page only needs 5), and commodity data, order data, evaluation data, recommendation data, inventory data, etc., may be required in the commodity details page. In the earliest design, the detail page may need to request 6 interfaces, which is very poor experience for the client and web page. In a new design, the BFF interface of the detail page dynamically assembles the call interface, and a SINGLE BFF interface assembles the data and directly returns it to the business side, which has a very good experience

3. The V2.1

There are too many problems with the V2 architecture, which is not developed and implemented. To address the above, a new role, Mobile BFF, was introduced between the external device and the internal microservice. BFF, short for Backend for Frontend, is an adaptation service that ADAPTS back-end micro services (including aggregation tailoring and format adaptation logic) and exposes friendly and unified apis to wireless devices to facilitate the access of wireless devices to back-end services. The V2.1 service architecture is as follows

The advantages of this architecture are:

  • Wireless App and internal service are decouple. By introducing the introduction of BFF, the two sides can change independently:
    • If the back-end is changed, the front-end device is not affected by BFF shielding
    • If the front-end changes, through BFF shielding, back-end microservices can temporarily remain unchanged
    • When the wireless end has new requirements, BFF shielding can reduce the overhead of communication and collaboration between the front and back ends. Many requirements can be solved by the front end team on BFF
  • The wireless App only needs to know the address of Mobile BFF, and the service interface is unified, without knowing the internal complex micro-service address and details
  • Aggregation clipping and adaptation logic in Mobile BFF, wireless App side can be simplified and thin

4. V3

V2.1 architecture was relatively successful, and supported the development of the company’s early wireless business for a long time after its implementation. With the rapid growth of business volume and the continuous increase of wireless RESEARCH and development team, the problems of V2.1 architecture were exposed:

  • Mobile BFF has various lines of business not only in the aggregate/cut/adapter and the business logic, also introduced a lot of across section of logic, such as security authentication, log monitoring, current-limiting fuse, etc., with the passage of time, the code is becoming more and more complex, more and more technical debt, development efficiency is declining, defect number increasing
  • The Mobile BFF cluster is a single point of failure. A serious code defect will cause a surge in traffic and may cause the cluster to go down, making all wireless applications unavailable

To solve the above false propositions, it was decided to construct a new layer between the external device and the BFF, namely Api Gateway. The V3 architecture is as follows:

The new architecture V3 has the following adjustments:

  • BFF is decoupled by team or business and divided into several BFF microservices. Each line of business can develop and deliver its own BFF microservices in parallel
  • The official level (usually operated by an independent framework team) focuses on cross-cutting functions, including:
    • Routing, which routes requests from wireless devices to a microservice BFF cluster at the back end
    • Authentication: centralized authentication of apis involving sensitive data
    • Monitor, for performance monitoring of Api calls
    • Current limiting fuses: When a traffic peak occurs, or the back-end BFF/ micro service is delayed or faulty, the gateway proactively implements the current limiting fuses to protect the back-end service and keep the front-end user experience acceptable.
    • Security Prevents crawling, collects access logs, analyzes malicious behaviors on the background, and blocks malicious requests.
  • The gateway introduces another layer of indirection between the wireless device and the BFF, allowing the two sides to change independently, especially when the back-end BFF is being upgraded or migrated, so that the client application is not affected

In the new the V3 architecture, gateway assume an important role, it is decoupled and subsequent upgrade migration tool, with the cooperation of the gateway, monolithic BFF to realize decoupling split, each business team can be developed independently and deliver their services, research and development to enhance the efficiency, in addition, the across section of logic from BFF, stripped to the gateway, BFF developers can focus more on business logic delivery, enabling a separation of architectural concerns.

5 V4

With the continuous development of business, the technical architecture also needs continuous iteration and upgrading. In recent years, the technical team has new business and technical requirements:

  • Open the internal business capabilities, build a development platform. Leveraging the capabilities of third-party community developers to further expand business formats
  • The traditional server-side Web application mode is abandoned, and the front and back end separated architecture is introduced. The front end adopts H5 single page technology to provide better user experience

V4 takes the same approach as V3, but expands the access channels:

  • BFF layer and corresponding gateway layer are introduced to support third-party developers to develop applications on the open platform
  • BFF and matching gateway for H5 applications are introduced to support the separation of front and back and H5 single page application mode

V4 is a relatively complete modern microservice architecture, from the outside to the inside is: end user experience layer -> gateway layer -> BFF layer -> microservice layer. The overall architecture is a flexible and evolving architecture that supports continuous business innovation with clear hierarchy and clear responsibilities

Conclusion:

  1. Backend for Frontend (BFF) is also called the aggregation layer or adaptation layer in the microservice architecture. BFF ADAPTS complex internal microservices into friendly and unified apis for different user experiences (such as wireless, Web, H5, and third-party). Aggregation tailoring is the main responsibility of BFF.
  2. In the microservices architecture, gateways focus on cross-sectional logic, including routing, security, monitoring, and current-limiting fuses. On the one hand, gateways are a powerful tool for decoupling and decoupling, while allowing developers to focus on the implementation of business logic and achieve architectural separation of concerns.
  3. End user experience layer -> gateway layer ->BFF layer -> microservice layer is a typical hierarchical mode of modern microservice architecture. This architecture can flexibly respond to the changes of business requirements and is an evolutionary architecture supporting innovation.
  4. Both the BFF and the gateway are products of architectural evolution as technology and business change and architects constantly adjust their architectures to respond to these changes.

2. BFF & GraphQL

There are two problems that are common in large front-end mode

  • Apis that change frequently need forward compatibility
  • Not all of the fields returned in BFF are required by the client

GraphQL was officially opened source by Facebook in 2015. It is not a language, but an API query style. This paper focuses on the design and evolution of BFF layer in big front-end mode, which needs to be implemented with GraphQL. Let’s take a look at GraphQL and see what Node or language solutions look like.

1. Use GraphQL

Server description Data – Client requests on demand – Server returns data

The server describes data

type Project {
  name: String
  tagline: String
  contributors: [User]
}
Copy the code

The client requests as needed

{
	Project(name: 'GraphQL') {
		tagline
	}
}
Copy the code

The server returns data

{
	"project": {
			tagline: "A query language for APIS"
	}
}
Copy the code

Characteristics of 2.

1. Define the data model and obtain it on demand

Just like writing SQL, describe the data that needs to be queried

2. Data layering

The data format is clear and semantic

3. Strong type and type verification

GraphQL has its own type description, type checking

4. Protocol, not storage

It looks a lot like MongoDB, but one is data persistence and one is interface query description.

5. Versioning is not required

For those of you who have written client code, When Apple deprecates an API, it will tell you why and what API to use instead. GraphQL also supports this, and also describes how to resolve the deprecation and how to use it.

3. When do YOU need BFF

  • The back end is used by many clients, and each client has customization requirements for the same Api class
  • There are many back-end microservices, and each microservice is focused on its own domain
  • Need to do some personalized optimization for the Api used in the front end

When is BFF not recommended

  • Back-end services are used by only one type of client
  • Back-end services are relatively simple and offer few opportunities for common services (DDD, microservices)

4. To summarize

Backend for Frontend (BFF) is also called re aggregation layer or adaptation layer in the micro service architecture. BFF ADAPTS complex internal micro services into friendly and unified apis for different user experiences (such as wireless, Web, H5, and third-party). Aggregation tailoring is the main responsibility of BFF.

In the microservices architecture, gateways focus on cross-sectional logic, including routing, security, monitoring, and current-limiting fuses. On the one hand, gateways are a powerful tool for decoupling and decoupling, while allowing developers to focus on the implementation of business logic and achieve architectural separation of concerns.

End user experience layer -> gateway layer ->BFF layer -> microservice layer is a typical hierarchical mode of modern microservice architecture. This architecture can flexibly respond to the changes of business requirements and is an evolutionary architecture supporting innovation.

Both the BFF and the gateway are products of architectural evolution as technology and business change and architects constantly adjust their architectures to respond to these changes.

4. Back-end architecture evolution

1. Explain some common nouns

Cloud Native is a way to build and run applications, a set of technical systems and methodologies. Cloud Native is a compound word, Cloud+Native. Cloud is a Cloud platform. Native applications take the Cloud environment into account at the beginning of design. They are designed for the Cloud and run in the best position on the Cloud, making full use of the flexibility and distributed advantages of the Cloud platform.

If software development is like a cook, Iaas is when someone else provides the basics like a kitchen, stove, pot, etc., and you use those things yourself and make different dishes for different needs. Service providers provide servers, usually cloud hosts, and customers build their own environments to deploy software. For example, Alibaba Cloud and Tencent Cloud are typical IaaS service providers.

Paas: For example, if I cook a braised chicken with rice, in addition to providing the basics, PaaS also provides you with ready-chopped chicken, potatoes, and peppers. All you have to do is put these things together, add some spices, and stew them in a small pot on the stove for 20 minutes. They only need to care about the software itself, as for the software running environment provided by service providers. PaaS are often referred to as cloud engines, cloud containers, etc.

This time, I only provide soy sauce, salad oil, salt, vinegar, MSG and other seasonings, but I don’t provide other seasonings. You can decide whether to put more salt or vinegar according to different tastes.

This time it is a small pot of chicken that is directly ready-made. What condiments are all good and it is already a finished product. As long as you put a label on it and sell it directly, it is mostly stewed on the stove for 20 minutes. This is the concept of Software as a Service (SaaS), where you buy Software already developed by a third-party Service provider and use it without having to build a team to develop it yourself.

Baas: You realize that if you want to change something, you only need to change the front end, and you don’t need to change the back end at all. At this time you think, you can recruit a front-end engineer, front-end page to do their own, back-end part or service providers.

Backend as a Service (BaaS). You only need to develop the front end and the rest is handed over to the Service provider. Often said “back-end cloud” is the meaning of BaaS, such as LeanCloud, Bomb and other typical BaaS service providers.

MicroService vs Severless: MicroService is a MicroService, which is a small service focusing on a single responsibility and function. Serverless is equivalent to a more fine-grained and fragmented single responsibility and function small service. They are all specific small services.

MicroService vs Service Mesh: Before ServiceMesh, microservice communication and data exchange synchronization also exist, and there are better solutions, such as Spring Clould, OSS, Double, etc., but they have the biggest feature that you need to write code, and need to write a lot of deep logic operation code, which is intrusive. The biggest feature of ServiceMesh is that it is non-invasive and does not require you to write specific codes. It can only enjoy the communication between micro-services, data exchange and synchronization at the level of cloud services, such as Docker +K8s, Istio, Linkerd and so on.

2. Architecture evolution

The entire evolution of the back end can be shown in the figure above, which goes through continuous iterations. The specific explanation is not expanded here. In the same breath as SOA, there is an ESB (Enterprise Service Bus), which is simply a pipe connecting service nodes. To integrate services from different systems and protocols, an ESB can be simply understood as: it interprets messages and routes them so that different services can communicate with each other; Use an ESB to decouple dependencies between services

Differences between SOA and microservice architectures

  • Decentralize microservices, removing the ESB enterprise Bus. Microservices no longer emphasize the ESB enterprise service bus, which is more important in the traditional SOA architecture, while the idea of SOA enters into a single business system to achieve true componentization
  • The emergence of Docker container technology provides more convenient conditions for microservices, such as smaller deployment units. Each service can run in its own process through technologies like Node or Spring Boot.
  • SOA focuses on the system integration aspect, while microservices focuses on complete separation

REST API: Each business logic is decomposed into a microservice that communicates with each other through the REST API.

API Gateway: Develops API interfaces for terminal users or clients and performs tasks such as service routing, load balancing, caching, access control, and authentication.

Some common design patterns for the front end, BFF and back end

At the beginning of this article, my colleagues in our group recently implemented a set of Redux on the client, redesigning the functions of a certain business domain. Both iOS and Android follow this set of rules, namely, Redux. Why do you need a client to implement a set of Redux? The business logic of the commodity module is very responsible, and there is a lot of basic commodity information, such as multi-specification, multi-unit, price, inventory and other information, as well as corresponding store and online store models, as well as various industry ability switch control. The early implementation of Rx role, resulting in complex code logic and chaotic data flow. The architecture design and code maintenance are not very elegant. In addition, there is a big business adjustment recently, and the students in the middle stage reconstructed the business by Redux + one-way data flow.

IOS and Android declare DTO Model respectively, and then parse the data to generate the data required by the client. In this way, “repeated” behavior often occurs, so we simply use TS + script. The ability of the gateway data model to automatically generate iOS and Android models has been removed. However, when discussing the framework design, people refer to React Redux, Flutter Fish Redux, Vuex, etc., and talk about one-way data flow and two-way data flow. However, some students’ understanding is wrong. So the first part of this paper “error correction” part is to clarify the front several key concepts.

The rest is explained in logical order: microfront-end -> BFF/ gateway -> microservices.

First, correct the wrong questions

1. Is Vue a two-way data stream?

If the answer is “yes”, then you probably don’t understand the concepts of “two-way data flow” and “two-way binding”. In fact, the two are not exactly the same thing, one-way data flow can also achieve two-way binding.

In fact, if you look closely at the official documentation of Vue, it is stated that Vue is actually a one-way Data Flow. Here’s an official quote

To be clear, when we say data flow, we mean data flow between components. All props in Vue have a one-way downlink binding between their parent props: updates from the parent props flow back down to the child component, but not the other way around. This prevents accidental changes in the state of the parent component from the child component, making your application data flow difficult to understand.

In addition, every time the parent component changes, all props in the child component will be refreshed to the latest value, which means you should not modify prop in the child component, and if you do, the browser will issue a warning in the console. Vue and React props

React is MVVM?

Instead of answering that question directly, let’s talk about a couple of concepts, and once we’re clear about those concepts, the answer to that question will be clear.

2.1 Differences between One-way binding and bidirectional binding?

Binder is a must when it comes to MVVM. One-way binding and bidirectional binding.

Vue supports one-way binding and bidirectional binding. A one-way binding is an association between a Model and a View, such as v-bind. Two-way binding means that updates to the Model are synchronized to the View, and changes to the View are automatically synchronized to the Model, such as the V-Model.

V-model is actually syntax sugar, because Vue is a tamplate, so after webpack AST parsing, tamplate will become render, v-model will become V-bind and V-ON

One-way binding + Auto Event Binding is a simple way to achieve the effect of two-way binding. The following

In fact, a look at the source code will find (Vue3 Proxy), one-way binding and two-way binding difference is that two-way binding to the data change part of the operation, by the framework of the internal implementation, the caller does not need to perceive.

2.2 Redux

A typical flowchart for using React Redux is as follows

If we hide the implementation of action and Dispatcher inside the framework, the diagram can be simplified as

If further, we hide the mechanism of mutual manual notification, which can be simplified as

If you look closely, is it MVVM? The answer to that question is obvious. React is not MVVM.

3. Is Vue MVVM

The official states that “it is inspired by MVVM, although it does not follow MVVM ideas exactly. So when we Debug, we often see that changes to the VM “Model” will trigger an update to the View. This is reflected in v-bind. Changes to the View, even if they are synchronized to the Model, are reflected in the V-Model. But Vue breaks the MVVM specification by providing the Ref attribute, which allows you to use the Ref to retrieve the Dom and manipulate some of its styles or attributes directly

4. Usage scenarios of one-way binding and bidirectional binding

Why did Vue remove.sync and Angular add < for one-way binding?

As applications get bigger and bigger, two-way data flows can bring unexpected results that complicate debugging, debugging, and testing.

So Both Vue and Angular realized this and removed.sync in favor of one-way binding.

Talk about the problem head-on:

The benefits of one-way binding, which brings one-way data flow, are that all state changes can be recorded and tracked. State changes must be notified by manual invocation and traced back to the source, without “black box operation”. At the same time, the component data only has a unique entrance and exit, making the program more intuitive and easier to understand, conducive to the maintainability of the application. The disadvantage is that the amount of code increases and the flow of data becomes longer for the same requirements. At the same time, due to strict requirements for independent management of application state (single global store), it is particularly tedious to deal with scenarios with more local states (such as “rich form” applications with more user input and interaction).

The advantage of bidirectional binding is that it simplifies a lot of business-independent code in a scenario where forms interact a lot. The disadvantage is that due to the “black box operation”, local state changes cannot be traced, and too many potential behaviors increase the difficulty of debugging when errors occur. At the same time, as component data changes from more than one source of entry becomes possible, programmers are uneven, the written code is easy to make the direction of data flow disorder, the quality of the entire application is not controllable.

Conclusion: One-way binding and two-way binding are basically complementary in function, so we can use the right method in the right scenario. For example, in UI controls (usually form-like operations), data can be bound in a bi-directional manner; Other scenarios use one-way binding

Two, micro front end

Vue, React, one-way data flow, and two-way data flow mentioned above are all organized and designed for a single application. However, there will be some problems when the application is very large. Which brings us to today’s theme, “the micro front end.”

As you all know on the client side, we’ve been using componentization and modularization to split code and logic for a long time. So you can say what is a component and what is a module?

Component is to extract the repeated code to merge into a component, component emphasizes reuse, located at the bottom of the system, other functions are dependent on components, strong independence

Module refers to the code belonging to the same function/business is isolated into independent modules, which can run independently. It is divided into different modules based on pages and functions, and located in the business architecture layer.

These concepts are also true in the front end. For example, those who have written Vue and React know that a page needs to be split into components. A large page consists of multiple UI sub-components. Modules are the same, the front end uses self-executing functions (IIFE) for modularity, mature CommonJS, AMD, CMD, UMD specifications, etc. For example, the iOS side uses modularity to realize the separation of business domains such as goods, inventory and billing, and also realizes basic capability modules such as routing library and network library. The front end is more about modularity for namespace and code reuse

In fact, it can be seen that the front end, the client implementation of modular, componentization of the goal is the idea of divide and conquer, more is to stand in the code level of separation, organization management. However, as front-end engineering becomes more and more heavy, it is difficult for traditional front-end architecture to follow the idea of “agile”.

1. What is a micro front end

People who care about technology hear microfrontend and immediately think of microservices. Microservices are a variant of service-oriented architecture that designs applications as a series of loosely coupled, fine-grained services organized by lightweight communication protocols. Older and heavier front-end engineering faced the same problem, and it was natural to borrow the idea of microservices from the front end.

To get back to business, micro-frontends are a microservices-like architecture that applies the concepts of microservices to the browser side, transforming Web applications from single monolithic applications into aggregations of small front-end applications. Each front-end application can also run, develop and deploy independently. A microfront-end is not a simple front-end framework or tool, but a set of architecture.

Characteristics of 2.

2.1 Technology independent

Throw two scenarios and think about it:

  • You’re new to a company, and your boss throws you a five-year-old project that you need to iterate on and add features to.
  • When you start a new project, your boss, who is used to seeing the ups and downs of technology at the front end, only gives you one architectural requirement: “How do you make sure that this technical solution is still viable in 3 to 5 years and will not become another legacy project in 3 to 5 years?”

For the first scene we thought, ok, I’ll just use React/Vue. They’re just UI libraries anyway, so give me a Dom node and I’ll render it as I want. But have you ever considered that this is just the view implementation floating on the surface, the engineering infrastructure sinking underneath? How do I package the React component and integrate it into the original ES5 code? Or how do I get Webpack and Grunt to coexist in a friendly way to produce a Bundle that meets expectations?

Second scenario, how do you ensure that the technology stack remains viable for 3-5 years? Don’t cross frameworks. Even React 15 and 16 are not compatible. Hooks cannot be used in Class Component. There is also the packaging scheme, now it is good to default Webpack, how about the Webpack version upgrade, do you follow up every time? Don’t forget Babel, less, typescript, etc.? How many people can guarantee that their project will still be running after a year with all dependencies updated to the latest, let alone 3 years?

The reason for these two scenarios is that if we look at the companies in the industry that have made noise about “micro front ends”, we will find that adopt micro front ends are basically ToB software services, and no ToC companies have micro front ends (some are also internal middle and back end systems). Why is this? Simple, because few ToC software will survive more than three years. For ToB applications, 3 to 5 years is too common. Go to see ali cloud earliest those products console, go to see those telecom software, banking software, which is not 10 years + life? I won’t say much about how painful it is to upgrade enterprise software. So the core appeal of most enterprise applications is how do I make sure my legacy code migrates smoothly, and how do I make sure I still have access to the hot technology stack years from now?

How to continue the legacy project is our initial appeal to the micro front end. Many development may not feel deep, after all, those who make millions, a year’s worth of projects either die, or is thrown to the outsourcing team maintenance, but want to know, to do a lot of small and medium-sized enterprises in the field of ToB, such a system might be their living, can not say it is, they can’t bear such a high cost of trial and error.

Even for new business, each technical team should be able to choose the appropriate technology stack according to the technical reserve of its own team members and business characteristics, without paying special attention to the situation of other teams. That is, team A can use React, team B can use Vue, and team C can even use Angular to implement it.

2.2 Simple, loosely coupled code base

Microfront-end architecture is much smaller and easier to develop and maintain than a whole front-end engineering. In addition, it is more important to avoid the increase in complexity caused by unreasonable implicit coupling between modules. Well-defined application boundaries reduce the likelihood of accidental coupling, increase the cost of logical coupling between sub-applications, and force developers to be clear about the flow of data and events through the application

2.3 Incremental Upgrade

The ideal code would naturally be modular, dependent, easy to extend, easy to maintain… In practice, however, for a variety of reasons:

  • History project, family code
  • Deliver pressure, then fast
  • Close to ripe, then stability……

There is always less than ideal code:

  • Backward technology stack, and even forced to mix multiple technology stack
  • Coupling chaos, dare not move, pull a restless body
  • Incomplete reconstruction, reconstruction – rotten tail, change posture reconstruction – rotten tail again…

The biggest problem with a complete refactoring of this code is that it’s hard to have the resources to do it all at once, ensuring a smooth transition in the middle while still delivering new features:

So, in order to implement progressive refactoring, we need an incremental upgrade capability that allows the old code to coexist with the new, and then gradually transform the old code until the entire refactoring is complete

This incremental upgrade capability means that we can make low-risk partial replacements of product features, including upgrade dependencies, replacement architectures, UI reworks, and so on. On the other hand, it also brings flexibility in technology selection, which is conducive to experimental trial and error of new technologies and new interaction modes

2.4 Independent Deployment

The ability to deploy independently is critical in a microfront-end architecture, narrowing the scope of change and thus reducing the associated risk

Therefore, each microfront should have its own continuous delivery pipeline (including build, test, and deploy to production) and be able to be deployed independently without much consideration for the current state of other code bases and delivery pipelines:

If Biz A, B and C have three systems, the three can be deployed independently, and finally the main system will integrate and release the application. It’s more independent and flexible. If you think about A single application in the past, such as A complex business application, it would be very likely that the entire application would fail when B was built without passing Lint, which would not only waste time building A, but also make the entire application build serial and inefficient.

2.5 Team Autonomy

In addition to code and release cycle on the decoupling, micro front also helps to form an independent team, by different team is responsible for a piece of their independent functions of products, according to the division Biz to best, because the code are independent, so the front-end based on Biz business team, can design thinking, provide a more reasonable interface and ability. Even more basic capabilities can be abstracted, providing more complete capabilities in line with business thinking, that is, more autonomy for the team.

3 How to Implement it

The micro front end mainly adopts the combined application routing scheme. The core idea of the scheme is “master and slave” (are those who have played Jenkins familiar with it?), that is, it includes a base “MainApp” application and several micro applications (MircroApp). Mainly be responsible for the application for registration, route map, such as the issuance of the news, and the application is the front end of the project independently, these projects are not limited to the specific technology (React, Vue, presents, Jquery), etc., each application registered to the base, run by base, even without the base, these applications can access alone, as follows:

The problems that a microapplication framework needs to solve are:

  • Route switchover distribution problem

    The base application, as a micro-front-end, is the entrance of the whole application and is responsible for carrying the display of the current micro-application and forwarding of other routing micro-applications. The display of the current micro-application is generally composed of the following steps:

    1. As a SPA base application, it is a set of pure front-end projects. In order to display the page of micro-application, iframe should be adopted and the page content of micro-application should be pulled first, which requires the remote pull mechanism.
    2. The remote pull mechanism usually uses the FETCH API to fetch the HTML content of the micro-application first, then extracts the JavaScript and CSS of the micro-application through parsing, and runs the JavaScript using eval method. And append CSS and HTML content to the display area reserved for the micro-application in the base application. When the micro-application switches, unload these contents synchronously, which constitutes the display process of the current application.
    3. Of course, this process will involve CSS style pollution and JavaScript pollution of global objects, which will be discussed later. At present, there are ready-made libraries to implement the process of remote pull mechanism, you can refer to import-HTML-entry and system.js.

    As for route distribution, the base SPA application developed by VUe-Router is taken as an example, which is mainly the following process:

    1. When the browser’s path changes, vue-Router listens for a Hashchange or popState event to determine the timing of a route switch.
    2. The router of the base is the first to receive this change. By querying the registration information, it can obtain the route forwarded to the micro-application. After some logic processing, it uses the modified Hash method or pushState method to route the information to the micro-application. Microapplications can manually listen for hashchange or popState event reception, or use react-Router or vue-Router to take over the route. The logic is then controlled by the microapplication itself.
  • Isolation of master and micro applications

    Application isolation problems are mainly divided into main application and micro application, JavaScript execution environment isolation between micro application and micro application, CSS style isolation, let’s talk about CSS isolation first.

    CSS isolation: When the main application and micro-application render on the same screen, some styles may pollute each other. If you want to completely isolate CSS pollution, you can use CSS Module or namespace to give each micro-application Module a specific prefix to ensure that it will not interfere with each other. You can use postCSS plug-in of Webpack. Add specific prefixes at packaging time.

    CSS isolation between microapplications is very simple, marking all the link and style content of the application each time the application loads. After the application is uninstalled, synchronize the corresponding Link and style on the uninstallation page.

    JavaScript isolation: Whenever a microapplication JavaScript is loaded and run, its core is actually the modification of the global object Window and some global events. For example, jQuery will mount a window.$object on the Window after it is run. To do this, you need to load and unload each microapplication while eliminating this conflict and impact as much as possible, most commonly by using a SandBox mechanism.

    The core of the sandbox mechanism is to keep the local JavaScript runtime’s access to and modification of external objects under control, meaning that no matter what happens inside, it doesn’t affect external objects. The VM module is usually used on the Node.js side, but for the browser, you need to sandbox the browser side with the with keyword and the window.proxy object.

  • Communication problems

    There are many ways to communicate between applications, but of course, communication between separate microapplications is essentially dependent on intermediaries or global objects. Therefore, the communication mechanism of message subscription (PUB/SUB) mode is very suitable. In the base application, the Event center is defined, and each micro-application registers the Event separately. When the Event is triggered, the Event center distributes the Event uniformly, which constitutes the basic communication mechanism.

At present open source many micro front-end frameworks, such as Qiankun, interested can go to see the source code

4. Check whether to use a micro front end

Why do a micro front end? Or what problem does the micro front end solve? That answers the question of whether a micro front end is needed. Single-spa, the ancestor of the microfront, initially solved the problem of using a new technology stack in an old project. At the present stage, another major problem to be solved by the micro front end announced by Ant Financial Qiankun is the difficulty in maintenance and collaborative development of boulder project. If the project is facing both of these problems, I think the micro front end is a good place to try. What do you think?

3. Thoughts on constructing BFF based on GraphQL in microservice platform

1. Large front-end architecture evolution

Let’s tell a story

1. V1

Suppose that in early 2011, an e-commerce company completed the separation of single applications and the back-end services had been SOA-BASED. At this time, the application form was only Web. The V1 architecture diagram is as follows:

2. V2

Time came to the beginning of 2012, domestic blowing a gust of wireless application wind, each big factory began their own wireless application development. To address this requirement, the architecture was adjusted to V2, as shown below

There are some problems with this architecture:

  • Wireless APPS and internal microservices are strongly coupled, and changes on either side may affect the other

  • Wireless apps need to know the internal service details

  • The wireless App side needs to do a lot of aggregation tailoring and adaptation logic

    Aggregation: A single page may require several back-end apis to be combined simultaneously, such as the data required for a product detail page, which cannot be done in one call

    Tailoring: The basic services provided by the back-end are universal, and the Payload returned by the App is large and has too many fields. The App needs to tailor the fields according to the device and service requirements. Is the user’s client Android or iOS, large or small screen, and version? For example, which industry does the business belong to, what is the product form, what scenario is the function put in, who is the user group for and so on. These factors all lead to differences in the logic of the end – oriented functionality. In the context of microservices and domain-driven design (which is not the focus of this article), each service provides the basic functions of the current Domain, such as the commodity Domain, which provides the function of adding, querying and deleting goods, list function and detail page function.

    But in the case of the item detail page, the data requires the ability to invoke the item domain, the inventory domain, and the order domain. The client needs to do a lot of network interface processing and data processing.

    Adaptation: Some common adaptation is format conversion. For example, some back-end services are older and provide SOAP/XML data but do not support JSON. In this case, some adaptation code is required

  • As the usage types increase (iOS Phone/Pad, Android Phone/Pad, Hybrid, applets), the development of aggregation tailoring and adaptation logic can cause a lot of repetitive work on the device side

  • Front-end such as iOS, Android, small program, H5 biz all need business data. The earliest design was a straight out back-end interface. This design causes a problem because biz1 is iteratively released, resulting in the implementation of the back-end change interface. Another requirement of Biz2 will cause the server side to change the design implementation, resulting in a business-oriented interface. Are the underlying services developed for business interfaces at all? This is a departure from domain-driven design

In this context, the BFF (Backend For Frontend) layer was born. Each field provides basic data model, and each biz has its own BFF layer. Query on demand (for example, commodity basic data is 200, but the small program list page only needs 5), and commodity data, order data, evaluation data, recommendation data, inventory data, etc., may be required in the commodity details page. In the earliest design, the detail page may need to request 6 interfaces, which is very poor experience for the client and web page. In a new design, the BFF interface of the detail page dynamically assembles the call interface, and a SINGLE BFF interface assembles the data and directly returns it to the business side, which has a very good experience

3. The V2.1

There are too many problems with the V2 architecture, which is not developed and implemented. To address the above, a new role, Mobile BFF, was introduced between the external device and the internal microservice. BFF, short for Backend for Frontend, is an adaptation service that ADAPTS back-end micro services (including aggregation tailoring and format adaptation logic) and exposes friendly and unified apis to wireless devices to facilitate the access of wireless devices to back-end services. The V2.1 service architecture is as follows

The advantages of this architecture are:

  • Wireless App and internal service are decouple. By introducing the introduction of BFF, the two sides can change independently:
    • If the back-end is changed, the front-end device is not affected by BFF shielding
    • If the front-end changes, through BFF shielding, back-end microservices can temporarily remain unchanged
    • When the wireless end has new requirements, BFF shielding can reduce the overhead of communication and collaboration between the front and back ends. Many requirements can be solved by the front end team on BFF
  • The wireless App only needs to know the address of Mobile BFF, and the service interface is unified, without knowing the internal complex micro-service address and details
  • Aggregation clipping and adaptation logic in Mobile BFF, wireless App side can be simplified and thin

4. V3

V2.1 architecture was relatively successful, and supported the development of the company’s early wireless business for a long time after its implementation. With the rapid growth of business volume and the continuous increase of wireless RESEARCH and development team, the problems of V2.1 architecture were exposed:

  • Mobile BFF has various lines of business not only in the aggregate/cut/adapter and the business logic, also introduced a lot of across section of logic, such as security authentication, log monitoring, current-limiting fuse, etc., with the passage of time, the code is becoming more and more complex, more and more technical debt, development efficiency is declining, defect number increasing
  • The Mobile BFF cluster is a single point of failure. A serious code defect will cause a surge in traffic and may cause the cluster to go down, making all wireless applications unavailable

To solve the above false propositions, it was decided to construct a new layer between the external device and the BFF, namely Api Gateway. The V3 architecture is as follows:

The new architecture V3 has the following adjustments:

  • BFF is decoupled by team or business and divided into several BFF microservices. Each line of business can develop and deliver its own BFF microservices in parallel
  • The official level (usually operated by an independent framework team) focuses on cross-cutting functions, including:
    • Routing, which routes requests from wireless devices to a microservice BFF cluster at the back end
    • Authentication: centralized authentication of apis involving sensitive data
    • Monitor, for performance monitoring of Api calls
    • Current limiting fuses: When a traffic peak occurs, or the back-end BFF/ micro service is delayed or faulty, the gateway proactively implements the current limiting fuses to protect the back-end service and keep the front-end user experience acceptable.
    • Security Prevents crawling, collects access logs, analyzes malicious behaviors on the background, and blocks malicious requests.
  • The gateway introduces another layer of indirection between the wireless device and the BFF, allowing the two sides to change independently, especially when the back-end BFF is being upgraded or migrated, so that the client application is not affected

In the new the V3 architecture, gateway assume an important role, it is decoupled and subsequent upgrade migration tool, with the cooperation of the gateway, monolithic BFF to realize decoupling split, each business team can be developed independently and deliver their services, research and development to enhance the efficiency, in addition, the across section of logic from BFF, stripped to the gateway, BFF developers can focus more on business logic delivery, enabling a separation of architectural concerns.

5 V4

With the continuous development of business, the technical architecture also needs continuous iteration and upgrading. In recent years, the technical team has new business and technical requirements:

  • Open the internal business capabilities, build a development platform. Leveraging the capabilities of third-party community developers to further expand business formats
  • The traditional server-side Web application mode is abandoned, and the front and back end separated architecture is introduced. The front end adopts H5 single page technology to provide better user experience

V4 takes the same approach as V3, but expands the access channels:

  • BFF layer and corresponding gateway layer are introduced to support third-party developers to develop applications on the open platform
  • BFF and matching gateway for H5 applications are introduced to support the separation of front and back and H5 single page application mode

V4 is a relatively complete modern microservice architecture, from the outside to the inside is: end user experience layer -> gateway layer -> BFF layer -> microservice layer. The overall architecture is a flexible and evolving architecture that supports continuous business innovation with clear hierarchy and clear responsibilities

Conclusion:

  1. Backend for Frontend (BFF) is also called the aggregation layer or adaptation layer in the microservice architecture. BFF ADAPTS complex internal microservices into friendly and unified apis for different user experiences (such as wireless, Web, H5, and third-party). Aggregation tailoring is the main responsibility of BFF.
  2. In the microservices architecture, gateways focus on cross-sectional logic, including routing, security, monitoring, and current-limiting fuses. On the one hand, gateways are a powerful tool for decoupling and decoupling, while allowing developers to focus on the implementation of business logic and achieve architectural separation of concerns.
  3. End user experience layer -> gateway layer ->BFF layer -> microservice layer is a typical hierarchical mode of modern microservice architecture. This architecture can flexibly respond to the changes of business requirements and is an evolutionary architecture supporting innovation.
  4. Both the BFF and the gateway are products of architectural evolution as technology and business change and architects constantly adjust their architectures to respond to these changes.

2. BFF & GraphQL

There are two problems that are common in large front-end mode

  • Apis that change frequently need forward compatibility
  • Not all of the fields returned in BFF are required by the client

GraphQL was officially opened source by Facebook in 2015. It is not a language, but an API query style

1. Use GraphQL

Server description Data – Client requests on demand – Server returns data

The server describes data

type Project {
  name: String
  tagline: String
  contributors: [User]
}
Copy the code

The client requests as needed

{
	Project(name: 'GraphQL') {
		tagline
	}
}
Copy the code

The server returns data

{
	"project": {
			tagline: "A query language for APIS"
	}
}
Copy the code

Characteristics of 2.

1. Define the data model and obtain it on demand

Just like writing SQL, describe the data that needs to be queried

2. Data layering

The data format is clear and semantic

3. Strong type and type verification

GraphQL has its own type description, type checking

4. Protocol, not storage

It looks a lot like MongoDB, but one is data persistence and one is interface query description.

5. Versioning is not required

For those of you who have written client code, When Apple deprecates an API, it will tell you why and what API to use instead. GraphQL also supports this, and also describes how to resolve the deprecation and how to use it.

3. When do YOU need BFF

  • The back end is used by many clients, and each client has customization requirements for the same Api class
  • There are many back-end microservices, and each microservice is focused on its own domain
  • Need to do some personalized optimization for the Api used in the front end

When is BFF not recommended

  • Back-end services are used by only one type of client
  • Back-end services are relatively simple and offer few opportunities for common services (DDD, microservices)

4. To summarize

Backend for Frontend (BFF) is also called re aggregation layer or adaptation layer in the micro service architecture. BFF ADAPTS complex internal micro services into friendly and unified apis for different user experiences (such as wireless, Web, H5, and third-party). Aggregation tailoring is the main responsibility of BFF.

In the microservices architecture, gateways focus on cross-sectional logic, including routing, security, monitoring, and current-limiting fuses. On the one hand, gateways are a powerful tool for decoupling and decoupling, while allowing developers to focus on the implementation of business logic and achieve architectural separation of concerns.

End user experience layer -> gateway layer ->BFF layer -> microservice layer is a typical hierarchical mode of modern microservice architecture. This architecture can flexibly respond to the changes of business requirements and is an evolutionary architecture supporting innovation.

Both the BFF and the gateway are products of architectural evolution as technology and business change and architects constantly adjust their architectures to respond to these changes.

4. Back-end architecture evolution

1. Explain some common nouns

Cloud Native is a way to build and run applications, a set of technical systems and methodologies. Cloud Native is a compound word, Cloud+Native. Cloud is a Cloud platform. Native applications take the Cloud environment into account at the beginning of design. They are designed for the Cloud and run in the best position on the Cloud, making full use of the flexibility and distributed advantages of the Cloud platform.

If software development is like a cook, Iaas is when someone else provides the basics like a kitchen, stove, pot, etc., and you use those things yourself and make different dishes for different needs. Service providers provide servers, usually cloud hosts, and customers build their own environments to deploy software. For example, Alibaba Cloud and Tencent Cloud are typical IaaS service providers.

Paas: For example, if I cook a braised chicken with rice, in addition to providing the basics, PaaS also provides you with ready-chopped chicken, potatoes, and peppers. All you have to do is put these things together, add some spices, and stew them in a small pot on the stove for 20 minutes. They only need to care about the software itself, as for the software running environment provided by service providers. PaaS are often referred to as cloud engines, cloud containers, etc.

This time, I only provide soy sauce, salad oil, salt, vinegar, MSG and other seasonings, but I don’t provide other seasonings. You can decide whether to put more salt or vinegar according to different tastes.

This time it is a small pot of chicken that is directly ready-made. What condiments are all good and it is already a finished product. As long as you put a label on it and sell it directly, it is mostly stewed on the stove for 20 minutes. This is the concept of Software as a Service (SaaS), where you buy Software already developed by a third-party Service provider and use it without having to build a team to develop it yourself.

Baas: You realize that if you want to change something, you only need to change the front end, and you don’t need to change the back end at all. At this time you think, you can recruit a front-end engineer, front-end page to do their own, back-end part or service providers.

Backend as a Service (BaaS). You only need to develop the front end and the rest is handed over to the Service provider. Often said “back-end cloud” is the meaning of BaaS, such as LeanCloud, Bomb and other typical BaaS service providers.

MicroService vs Severless: MicroService is a MicroService, which is a small service focusing on a single responsibility and function. Serverless is equivalent to a more fine-grained and fragmented single responsibility and function small service. They are all specific small services.

MicroService vs Service Mesh: Before ServiceMesh, microservice communication and data exchange synchronization also exist, and there are better solutions, such as Spring Clould, OSS, Double, etc., but they have the biggest feature that you need to write code, and need to write a lot of deep logic operation code, which is intrusive. The biggest feature of ServiceMesh is that it is non-invasive and does not require you to write specific codes. It can only enjoy the communication between micro-services, data exchange and synchronization at the level of cloud services, such as Docker +K8s, Istio, Linkerd and so on.

2. Architecture evolution

Figure 1. The evolution

The entire evolution of the back end can be seen in the figure above. It has gone through successive iterations and is now in the era of microservices and Service Mesh. Specific explanation is not done here, interested can go to their own Google. There is also an ESB (Enterprise Service Bus) in the same class as SOA. Simply put, an ESB is a pipeline connecting service nodes to integrate services across different systems and protocols.

The ESB can be simply understood as: it interprets and routes messages, allows different services to communicate, and decouples the dependencies between services using the ESB.

2. Differences between SOA and microservices architectures

Decentralize microservices, removing the ESB enterprise Bus. Microservices no longer emphasize the ESB enterprise service bus, which is more important in the traditional SOA architecture, while the idea of SOA enters into a single business system to achieve true componentization

The emergence of Docker container technology provides more convenient conditions for microservices, such as smaller deployment units. Each service can run in its own process through technologies like Node or Spring Boot.

SOA focuses on the system integration aspect, while microservices focuses on complete separation

3. Early microservices architecture

REST API: Each business logic is decomposed into a microservice that communicates with each other through the REST API.

API Gateway: Develops API interfaces for terminal users or clients and performs tasks such as service routing, load balancing, caching, access control, and authentication

Each business logic is decomposed into a microservice that communicates with each other through REST apis. Some microservices also develop apis to end users or clients. Typically, however, these clients do not have direct access to backend microservices, but instead pass requests through the API Gateway. The API Gateway is generally responsible for service routing, load balancing, caching, access control, and authentication.

4. The circuit breaker

The basic idea behind circuit breakers is very simple. You wrap protected function calls in a circuit breaker object that monitors failures. Once a fault reaches a certain threshold, the circuit breaker will jump

Gate, and all further calls to the circuit breaker return an error, and no protected calls are made at all. Typically, you also need some kind of monitor alarm if the circuit breaker trips.

Typically, foundations such as circuit breakers and service discovery implement independent access.

6. Problems and solutions of early microservice architecture

  • There are too many frameworks/SDKS, which makes subsequent upgrade and maintenance difficult
  • Service governance logic is embedded in business applications and occupies business service resources
  • Service governance policies are difficult to be unified
  • Maintenance costs of additional service governance components (middleware)
  • Multi-language: With the rise of Node, Java and other back-end services, it may be necessary to develop multiple sets of basic components to cooperate with the main application access, and SDK maintenance costs are high

Random introduction of Sidecar mode:

Binding these base services and applications together, but deployed using separate processes or containers, provides a homogeneous interface to platform services across languages. SideCare many people will be confused, how to understand this word, the picture below, next to the small tuo more image.

Advantages of Sidecar mode

  • Independent of its main application in terms of runtime environment and programming language, there is no need to develop a Sidecar for each language
  • Sidecar can access the same resources as the main application
  • Because it is close to the main application (deployed together), there is no noticeable delay in communicating between them
  • Even for applications that do not provide extensibility mechanisms, sidecar can be extended by attaching it as its own process to the host or subcontainer of the main application

7. Formation of Service Mesh

Each service will have a matching proxy sidecar, and since services only communicate with each other through the Sidecar proxy, we end up with a deployment similar to the following:

A service grid is a dedicated infrastructure layer that handles service-to-service communication. It is responsible for reliably delivering requests through the complex service topologies that make up modern cloud-native applications. In practice, service grids are typically implemented as a series of lightweight network agents that are deployed with application code that the application does not need to know about.

Grid = container grid + services

Typical Service Mesh architecture

Control layer:

  • The packet is not parsed directly
  • Communicates with agents on the control plane to deliver policies and configurations
  • Responsible for the visualization of network behavior
  • Apis or command-line tools are usually provided to configure versioning management for continuous integration and deployment

Data layer:

  • Stateless is usually designed with stateless goals in mind, but in practice some data needs to be cached to improve traffic forwarding performance, so stateless is also controversial
  • Direct processing of inbound and outbound data packets, forwarding, routing, health check, load balancing, authentication, authentication, monitoring data generation, etc
  • Transparent to the application, that is, it can be deployed without awareness

Istio is a typical mainstream Service Mesh framework. Detailed information about Istio can be found in the ebook here.

Write at the end

Why do client engineers need to read this? It doesn’t seem to have anything to do with everyday work, but knowledge is only useful if you accumulate it first, and then you have a chance to use it. Knowledge compounds, and knowledge and solutions in one area can give you ideas and perspectives to solve other problems. In addition, large front-end can not only deal with the client, front-end, back-end solutions, technical trends also need to understand, help you stand in a more macro perspective to solve a problem, clear design.