The vast majority of existing software systems will become legacy systems at some point in the future, just over a different time horizon. Good systems, with good design, evolve throughout their life cycle. But no design can withstand the changes of time and business.

Technology vision

You may have learned what BFF is in my previous article, or you may have learned about it from other sources. If not, let me briefly explain: what is BFF?

BFF

BFF, or Backends For Frontends, is that server apis are designed with the front-end in mind and the business logic is processed directly on the server side.

! [BFF)(http://architecture.phodal.com//images/bff.jpg)

As I mentioned in the History of Front-end Evolution, in the early days when we designed our system apis, we simply provided a JSON serialization of the Model for the front-end (Web, Android, iOS, etc.) without considering the specific needs of the front-end. The following is a general RESTful API that meets the requirements of RESTful apis by design, but is not suitable for use on the front end.

In this case, we need to do some processing, such as truncation of text and so on. Using BFF means that there is an additional layer of business processing and forwarding.

Applicable scenario

As mentioned above, this architecture is particularly suitable for system migration using the Strangler pattern.

The migration plan

Let’s go back to Web 1.0 and look at the architecture of websites back then:

How simple the system looks, since there is not much online business to try. Then, over a decade ago, we started working with mobile devices, adapting a layer of API:

The API that this layer ADAPTS to is not well designed. It might just be one by one putting the database Scheme:

CREATE TABLE contents (
  `id` int(11) DEFAULT NULL auto_increment PRIMARY KEY,
  `type` varchar(255),
  `title` varchar(255),
  `author` varchar(255),
  `body` text,
  http://architecture.phodal.com/.
) TYPE=MyISAM;Copy the code

These objects are converted into JSON in the code and then provided to the front end for use. As Web application interactions become more complex, the PC side is beginning to make extensive use of apis rather than background rendering:

Previously, the background directly returned the values in the database to the front end, and every time the values changed, Android, iOS, and The Web needed to make changes. At the same time, when we need to process a string, such as a limit of 140 characters, we need to implement it on each client (Android, iOS, Web), which is obviously quite expensive. Therefore, we need BFF as middleware. On this middleware we will do some business logic processing:

When we have this BFF layer, we don’t need to worry about the migration of the back end of the system. All backend changes can be modified in the BFF layer:

Until we refactor the front end and back end of the system to the new architecture, the front end and back end do not affect each other.

The test strategy

Considering the compatibility of the system,

Back on the test pyramid again, the old unit tests are necessarily not available because you are using a new system, a new language. Service testing and UI testing are compatible, depending on the design of the system.

Service test

In the background, we still read the database from the system, and the result should be the same — maybe from a different database, or maybe from ODBC to JDBC. For the front-end developer, nothing has changed in the background — of course, without the BFF isolation layer, multiple requests can become one request.

In the case of the above system, the generated URL and the title of the page should be unchanged, so we need to write tests corresponding to the URL and title to test:

The title, url Phodal 's guide Idea of actual combat, https://github.com/phodal/ideabook build iot system step by step, making https://github.com/phodal/designiot Growth: RePractise hitchhiker, https://github.com/phodal/github-roam, https://github.com/phodal/repractise Full stack Growth engineers guide, https://github.com/phodal/growth-ebook Growth: Full stack growth engineer of actual combat, https://github.com/phodal/growth-in-action and https://github.com/phodal/fe. My job is a front-end engineer Written for software engineers hardware programming guide, https://github.com/phodal/makeCopy the code

Write the OLD system’S URL tests first, then verify that the content is consistent one by one.

Conduct testing

In order to ensure compatibility between the old and new systems, it is necessary to perform automated UI testing to ensure that the new system works properly.

If our previous UI tests were written using the BDD architecture, we could continue with the previous behavior. In the meantime, we just need to change the implementation of the test script:

Take Cucumber as an example:

Suppose that when I enter username < username > when I enter password < password > when I submit login information then the Page should return "Error Page" example: | user name password | | | 'Jan1' | 'password' | | 'Jan2' | | 'password'Copy the code

If the business does not change, then these behaviors will not change, because it is the underlying implementation that changes. For example, if the id of the previous login button was login, now the id of the button may be changed to new_login. New_login is definitely a bad name, and the next time you refactor it will probably still be new_login.

Or ThoughtWorks Gauge:

Failed login = = = | user name password | | | -- -- -- -- -- -- -- - | -- -- -- -- -- -- -- - | | Jan1 | password | | Jan2 | password | failed login -- -- -- -- -- -- -- -- -- -- - * when I'm in the website homepage < user name > * * enter the user name Enter password < password > * Submit login information * The Page should return "Error Page"Copy the code

case

Two years ago, I worked on a real estate search site. It’s a very old system, so much so that when we fix bugs we see comments that are 10 years old. At the time, we used the Strangler model to rewrite the system, adding new functionality to the legacy system as a microservice.

Since this is a system that is already online, it is important to ensure that the old functionality is not broken during the rewrite process. In order to replace an unmaintainable search engine in the old system, we created an API service layer — in one API layer, we adapted the old search engine and developed an adaptation layer for the new search engine. Today, it counts as an implementation of BFF, and this migration approach is fairly reliable.

conclusion

However, it is not easy to adopt BFF directly from an older system. We need to isolate different environments and have a lot of technology ready.