The concept of the Central Taiwan has become very popular in recent years, and it is an inevitable trend. The server side is transformed into a medium platform, which can not avoid the use of micro services. After the back-end microsertization, it is different from our traditional collaborative development of front and back ends. Fortunately, we have also reformed the front-end development mode and framework in the mid-stage transformation of the company.

Server side microservitization

Common server-side languages include Java, PHP, c#, python, golang, nodejs, etc. Each language may need to choose different microservice RPC frameworks to implement microservices. The commonly used RPC frameworks are as follows:

  1. Dubbo, Java only

  2. Motan, C++ only

  3. Tars, Java only

  4. Spring Cloud, Java only

  5. GRPC, support for multiple languages

  6. Thrift supports multiple languages

At that time, the company mainly used Java as the server language, but the use of different department languages is different. Considering the support of multiple cross-platform languages, the COMPANY’s RPC framework uses Thrift.

Pre-microservitization development mode

Before server-side microservitization, the front – and back-end development model was very simple. The server side provided the interface and the front – end called directly. The Java API layer is the equivalent of the BFF(back-end For front-end), and strictly speaking any server language can do the BFF layer.

In this mode, the front end only needs to call the server-side API, and the server side does not care about the logic processing and mutual call relationship. The front end will let the server side provide what kind of interface the front end needs, which is also the development mode of many companies.

Development mode after microservitization

Server after service, can choose different RPC framework, in terms of our company, we chose the Thrift framework, the micro service provided to the outside world is the RPC interface, and the front end can not directly call the RPC interface, can only let Java developers provide HTTP interface, so that the server should write micro service layer, and to achieve BFF layer, The workload is self-evident, and the collaborative development of front and back end personnel is complicated. Let’s look at the development mode after microservitization:

Node acts as the BFF layer

If you implement microservices and BFF in Java, and Java developers are constantly changing the API logic based on the needs of the front end, is there a way for Java developers to focus only on the microservices layer, the front end would implement the BFF layer. It goes without saying that the front-end can implement BFF well, which is Nodejs’ strength. If the front-end implements BFF layer, the back-end personnel only need to focus on the logic of microservices, and then how the front-end needs to assemble these interfaces, which is implemented by Nodejs.

For those of you who haven’t used Node development, can Nodejs call RPC? The answer is yes, both gRPC and Thrift provide multilingual support.

How does Node call RPC

In traditional development mode, even if some companies use Node as the middle layer, Node only acts as a proxy. The front-end requests the interface provided by Node, and Node does not even do any logical processing, and directly passes through the Java layer through HTTP client or CURL:

In this way, Node is just a Proxy, which is useless in project development and even increases system maintenance costs. Let’s see how Node calls RPC. Take Thrift as an example and look at the Thrift definition:

Thrift is a lightweight cross-language RPC communication scheme that supports up to 25 programming languages. Like gRPC, Thrift also has its own interface definition language IDL to support multiple languages. It can generate SDK codes on the Client and Server sides of various programming languages through code generators, thus ensuring that different languages can communicate with each other

Interface Definition Language (IDL) is an Interface Definition Language (IDL). The Thrift website provides IDL production methods for various languages, including Nodejs.

Node calls Thrift RPC

There are two important steps in calling the thrift interface from the Node side:

  • The server side generates **. Thrift files from the interface definition tool
  • The front end gets the **. Thrift file and uses the tool to produce IDL files identified by Node

Use the command line tool to produce IDL files used by the Node

thrift -r --gen js:node tutorial.thrift
Copy the code

PS: Node’s direct call to RPC is really cumbersome, and different microserver interfaces have to generate a copy, causing Node to introduce a lot of Thrift IDL files. Let’s look at how Node calls an RPC interface after generating IDL using the command line tool:

const Calculator = require('./gen-nodejs/Calculator'); const ttypes = require('./gen-nodejs/tutorial_types'); const assert = require('assert'); const transport = thrift.TBufferedTransport; const protocol = thrift.TBinaryProtocol; const connection = thrift.createConnection("localhost", 9090, { transport : transport, protocol : protocol }); connection.on('error', function(err) { assert(false, err); }); // Create a Calculator client with the connection const client = thrift.createClient(Calculator, connection); client.ping(function(err, response) { console.log('ping()'); }); Add (1,1, function(err, response) {console.log("1+1=" + response); }); work = new ttypes.Work(); work.op = ttypes.Operation.DIVIDE; work.num1 = 1; work.num2 = 0; client.calculate(1, work, function(err, message) { if (err) { console.log("InvalidOperation " + err); } else { console.log('Whoa? You know how to divide by zero? '); }});Copy the code

As you can see, calling an RPC interface through thrift, both in terms of interface definition and parameter passing, is more complicated than calling an HTTP interface directly, which is one of the complications that makes Node a BFF layer.

Node BFF does more than provide apis

Above, we just took providing API as an example to explain how Node invokes the microservice RPC interface. However, in the actual project, Node BFF can provide more services, including routing, gateway, rendering, SSR, etc., and we also made such transformation in the real project.

The BFF model we used in the project:

BFF provides front-end capabilities:

  • The plug-in
  • The middleware
  • routing
  • Apply colours to a drawing

Node framework can be selected arbitrarily, including Express, Koa, Eggjs, Nestjs, etc. We chose Koa and then made the upper layer encapsulation based on Koa.

The plug-in

Provides a variety of built-in plug-ins, including Logger, HTTP Client, RPC Client, etc. Third-party plug-ins can also be configured to load

The middleware

One of the Gatway implementation methods, sso, current limiting, fusing and so on are implemented through middleware

routing

Routing provides different forms of API for different Appcations, whether H5, PC, applets or Open apis

Apply colours to a drawing

This layer can directly render the index.html generated by the Client build, and can also implement SSR

conclusion

In our real projects, DB may not be read or written to directly, but in some internal projects, DB can be read or written from Node without server side intervention. Node can also access cache middleware Redis, Memcache, etc., or even use messaging middleware MQ. If I wanted the BFF layer to be more flexible and easy to maintain, I felt it was better to use GraphQL as the gateway layer.