By Lanhao at Xianyu Technology
It has been more than half a year since Xianyu first explored the Flutter integrated development mode. The team at Xianyu Technology has published several articles on this matter and have shared our achievements in certain phases. Today, I would like to review Xianyu's path of integration from a general perspective.
Back in August 2019, Xianyu explored many innovative transaction modes every year. However, the code of the transaction chain was in disrepair and unable to provide responsive support to the business. In addition, the costs for maintenance was skyrocketing. The following figure shows an example:
In the figure above, we can see that:
At that time, we tried to refactor the transaction chain by using Flutter integration, so as to speed up development to better support innovative businesses.
The entire evolution process revolves around how to reduce the integration cost of clients, how to speed up overall development, and how to resolve pain points in business development.
In the order placement scenario, we formulated the following communication methods. Each on-client change and current data are sent to the server as a request. The server then calculates the new price for the requested action and returns the price to the client as a response. The convention between the two sides fully depends on a JSON structure. In this case, server code and client code markedly serve different purposes. For this reason, you need to know whether you are writing client code or server code (Functions as a Service (FaaS)), and then construct the desired data structure according to the JSON structure convention.
However, we still hope that the FaaS-layer code written by client developers could be as imperceptible as possible. FaaS encapsulates functions. For example, the client calls a function to increase the number of purchased items (for player's items only), and the returned value is the data for a new state, including the price. Some actions on the client can be regarded as functions, such as displaying a toast to warn against insufficient inventory, opening a specified page, or triggering the cashier. After the capabilities of both sides are functionalized, you can design a communication mode, as shown in the following figure.
In light of this communication method, we have designed a framework across FaaS and clients to function as the communication protocol between both sides, shielding the specific JSON format at the network layer. In addition, the function registration methods and action calling methods on both sides are the same, so that the specific locations of called functions are imperceptible to the developers. The following figure shows a sample code.
After the specific communication protocol is shielded to reduce communication cost, the next step is to design a new programming model. Client code development underwent the ages of Model-View-Controller (MVC), Model-View-Presenter (MVP), and Model-View-View Model (MVVM). With Flutter gaining popularity, the Flux concept has been implemented due to its distinct rendering mode from the rendering mode of Native. Flux defines principles for one-way data streams.
In light of Flutter integration, we have designed the following new programming model to maintain the integrity of the frontend and backend. This model contains a total of three modules: Render, Converter, and Model. Specifically, only the Render module is deployed on the client, and all rendering data on pages comes from the converted ViewModel (State) at the FaaS layer. When an interaction in the interface renders a state change necessary, the event is sent out and routed to the Model layer for processing.
Based on this event, the Model layer may pull the raw business data from the backend realm, and then the framework sends the data to the Converter module to convert the data state into the one required for rendering. In this way, code and modules are organized in a frontend-backend integrated manner, reducing communication costs.
The design described in the preceding section reduces client developers' FaaS programming complexity, helping establish and promote new production relationships. In addition to the transaction chain, we are also implementing similar integrations in other services and have set up a new mode of task division for frontend and backend developers. In this case, we call the FaaS layer the Serverless For Client (SFC) layer, which primarily provides user-oriented functions and supports inconstant features. This layer is responsible for aggregating, cropping, and structuring the data of various realms to serve the user layer on clients. As a result, server developers can focus more on realm construction.
Client-side developers often need to switch between integrated development environments (IDEs) when writing FaaS and Flutter code. This is quite effort-consuming, especially when a state needs to be modified. To address this issue, we place FaaS and Flutter business code under the same project directory, and make both of them dependent on common code (such as state and tool methods) in a one-way fashion. This way, the Flutter main project references a project to its project as a Git dependency. In the final compilation and deployment steps, the compilation tool selects the code in the corresponding directory for processing in order to fulfill the purpose described at the beginning.
Client developers' cost for programming the FaaS layer can be greatly reduced by building the communication layer and programming model, applying realm and middleware knowledge, and implementing project organization. Compared with the previous Flutter + server development mode, the integrated development mode removes processes including frontend-backend interface conventions, mocking data for development, writing duplicate code between the frontend and the backend, frontend-backend joint debugging, frontend-backend bug transfer during troubleshooting, and frontend-backend communication for modifying the interface protocol upon a problem. Collaborative communication is the biggest cost contributor. However, the transition to the new development also results in some other problems. For example, client developers need to study the interfaces of the business realm and understand the QPS, RT, and degradation policies of each interface, in addition to designing an overall business technical solution. Despite this, the cost is only incurred in the early stage and tends to zero as proficiency improves.
After we upgraded the transaction chain architecture to an integrated one, we addressed two innovative business requests this year. In the integrated architecture, only one client developer is required for review and development, and the entire development work can be done within half a day. These enhancements significantly accelerate the launch of new products and services. Additionally, even when a bug is detected at the user layer, only one developer is required for troubleshooting as the entire code was written by this developer. Therefore, the bug fixing efficiency improves.
Looking ahead, I hope this new client development mode can be implemented in more scenarios, so that more problems can be exposed and the entire infrastructure can be constantly improved into a better Alibaba Flutter solution and ultimately drive business development for greater values.
XianYu Tech - August 6, 2020
Alibaba Clouder - September 21, 2020
XianYu Tech - June 22, 2020
XianYu Tech - March 11, 2020
XianYu Tech - September 11, 2020
XianYu Tech - September 8, 2020
Visualization, O&M-free orchestration, and Coordination of Stateful Application ScenariosLearn More
Accelerate software development and delivery by integrating DevOps with the cloudLearn More
Web App Service allows you to deploy, scale, adjust, and monitor applications in an easy, efficient, secure, and flexible manner.Learn More
More Posts by XianYu Tech