Feelings about the separation of front and back ends

Feelings about the separation of front and back ends

Front-end and back-end separation is nothing new, and the practice of front-end separation is everywhere. However, some historical projects still inevitably encounter various problems when moving from an integrated Web design to a front-end and back-end separated architecture. Due to the endless problems, there are even team questions. The integration is good, why should the front and back ends be separated?

After all, it's not that the separation of front and back is not good, it's just that it may not be suitable, or... design thinking has not been transformed...

All-in-one Web Architecture

All-in-one Web Architecture


Schematic diagram of front and rear separation web architecture

Schematic diagram of front and rear separation web architecture

Why separate front and back

A more realistic question than why the front-end and back-end should be separated is when the front-end and back-end should be separated, that is, the application scenario of front-end and back-end separation.

Speaking of this problem, I think about 2011, the company expanded the Java team on the basis of the .NET development team. Although the two teams are working on different products, there are still a lot of repetitive development, such as I wrote the organization-related pages with ASP.NET WebPage, and I have to write it again with JSP. In this case, the team began to think about a solution: if the front-end implementation has nothing to do with the back-end technology, the page rendering part can be shared, and different back-end technologies only need to implement the back-end business logic.

The fundamental problem to be solved by the solution is to separate data and pages. The technology to meet this demand is readily available. The front-end uses static web page-related technologies, HTML + CSS + JavaScript, and invokes the business interface provided by the back-end through AJAX technology. The front-end and back-end negotiate the interface method and provide it through HTTP, and use the POST verb uniformly. The interface data structure is implemented in XML, the front-end jQuery is very convenient to parse XML, and the back-end has more processing tools for XML... Later, due to the rise of back-end JSON libraries (such as Newtonsoft JSON.NET, jackson, Gson, etc.), front-end processing JSON Also easier ( JSON.parse()and JSON.stringify()), just replace the data structure with a JSON implementation.

This architecture is essentially SOA (Service Oriented Architecture). When the backend does not provide pages, but only provides data and business interaction capabilities through Web API, the Web frontend becomes a pure client role, which belongs to the same role as WinForm and mobile terminal applications, and can be combined together. , collectively referred to as the front end . The previous integrated architecture requires custom pages to implement Web applications, and at the same time defines a set of WebService/WSDL to provide services to WinForms and mobile terminals. After the transition to the new architecture, all types of front ends can be served uniformly using the Web API form. As for the RPC encapsulation of this Web API by some type of front end, that's another story.

Through such architectural transformation, the front and back ends have actually been separated. Aside from other types of front-ends, only the web front-end and back-end are discussed here. Due to the separation, the front-end of the web does not need to know what technology the back-end is using when developing, just what kind of interface the back-end provides can be used to do things, such as C#/ASP.NET, Java/JEE , database... These technologies can all be ignored. The back-end .NET team and Java team are also separated from the aesthetic thinking that has nothing to do with logic. They do not need to face the fine interface design constraints of the artist, nor do they need to consider the layout of the page while thinking about the logic implementation. Just deal with the logic and data that you are good at.

After the front-end and back-end are separated, developers at both ends are much more relaxed. Because technology and business are more focused, development efficiency is also improved. The benefits of separation gradually became apparent:

1. Segregation of duties before and after

The front end tends to be presented, focusing on user experience-related issues; the back end tends to focus on business logic, data processing, and persistence. In the case of a clear design, the back-end only needs to be responsible for the business processing algorithms centered on the data, and provide API interfaces for the front-end as agreed; and the front-end uses these interfaces to be responsible for the user experience.

2. Separation of front and rear technologies

The front-end does not need to understand the back-end technology, and does not care what technology is used to implement the back-end. You only need to know HTML/CSS/JavaScript to get started; while the back-end only needs to care about the back-end development technology, in addition to saving the trouble of learning front-end technology , even the learning and research of the Web framework only needs to focus on Web API, not the MVC technology based on page view (not to say that MVC is not needed, the data structure presentation of the interface part of Web API is also View), do not need to consider special Complex data organization and presentation.

3. The separation of front and back brings the decoupling of user experience and business processing

The front-end can be quickly revised according to the experience needs of users in different periods, and the back-end has no pressure on this. In the same way, the business logic upgrade performed by the backend and the change of the data persistence scheme, as long as the interface is not affected, the frontend can be unaware. Of course, if changes in requirements cause interface changes, the front and back ends need to sit together to synchronize information.

4. The front and back are separated, and the designs at both ends can be reduced separately

The backend only provides API services and does not consider the issue of page rendering. The API that implements the SOA architecture can serve various front ends, not just the Web front end, and can achieve a set of services that can be used by all ends; at the same time, for the front end, the front end part that does not depend on the back end technology can be deployed independently, or can be In response to the Hybrid architecture, various "shells" (such as Electron, Codorva, etc.) are embedded to quickly realize multi-terminal.

Front and rear separation architecture

No technical solution is a silver bullet. The separation of front and rear not only brings benefits, but also brings contradictions. In the early stage of our practice, due to the relatively weak strength of the front-end team, and by convention, almost all business processing is designed and defined by the back-end (the original technical backbone). During the front-end processing, it is often found that the interface definition does not conform to the user operation process. , too many AJAX asynchronous requests, etc. After all, back-end thinking and front-end thinking are still different - front-end thinking is more inclined to user experience, while back-end thinking is more inclined to the technical implementation of business.

In addition, the safety requirements of front and rear separation are also slightly different. Since the separation of front and back is essentially a SOA architecture, authorization also needs to be thought in the way of SOA architecture. Although the Cookie/Session method is available, it is not particularly suitable. Relatively speaking, Token-based authentication is more suitable. Using Token-based authentication means that the authentication part of the back-end needs to be rewritten... Of course the back-end doesn't want to rewrite, so it will kick the ball to the front-end to let the front-end find a way to implement Cookie/Session-based authentication... So the front-end begins to complain ( tragedy)……

who will lead

The emergence of these contradictions, in the final analysis, is that the design is not clear enough. There is no doubt that in the development process, the leader should be the architect or designer. However, in actual scenarios, architects or designers are often developers, so their main technology stack will greatly affect the primary and secondary roles of the front-end and back-end in the entire project. Where this backbone is located, the convenience of development will lean to which side. This is a bad phenomenon, but we have to deal with this status quo, and I believe that many teams that are not too large are facing similar problems.

If there is no good process specification, usually the front-end will be exposed to more roles than the back-end (most application projects/products, not all cases).

  • Front-end developers will be directly influenced by the project/product manager or the client: there should be a button in this place, the action should go like this...;
  • The front end also needs to be connected with the artist - such a design is not easy to implement, can it be changed to that? The customer requires that this operation must be done, but this design cannot do it;
  • The front end also needs to be connected to the back end, and for some applications, even multiple back ends

In other words, the front end can become the center of project communication, so it is more suitable to take the leading role than the back end.

interface design

The interface is divided into two parts: back-end service implementation and front-end invocation. The technology is mature and not difficult, but the interface design is the difficulty. As mentioned earlier, there will be some contradictions between the front and back ends. From the front-end point of view, the focus is on user experience, including the flow direction and related processing of users during business operations; while from the back-end point of view, the focus is on data integrity, effectiveness, and security. The contradiction lies in the fact that the two sides have different concerns, information asymmetry, and their own interests. The focus of solving these contradictions is interface design.

When designing an interface, the size of its granularity often represents the size of the front-end and back-end workloads (not absolute, which is related to the overall architecture). If the granularity of the interface is too small, the front-end has to deal with many things, especially for various asynchronous processing. If the granularity is too large, high coupling will occur, reducing flexibility and scalability. Work is not easy. Things at the business level involve specific products, so I won't discuss them here. Here we mainly discuss a little bit of technical stuff.

Formally, Web API can be defined as REST or RPC, as long as the front-end and back-end are negotiated and determined. More importantly, in terms of input parameters and output results, it is best to have a relatively fixed definition from the beginning, which often depends on the front-end architecture or the UI framework used.

The data forms of common request parameters are as follows:

  • Key-value pair, used for QueryString in the URL or the payload of POST and other methods
  • XML/JSON/..., usually used for payloads such as POST, can also be passed using multipart
  • ROUTE, obtained by the back-end routing parsing URL, commonly used in RESTful

The data forms of the server response are varied. Usually, a complete response needs to contain at least three parts: status code, message, and data.

  • Status codes, HTTP status codes or specific status attributes in the response data
  • The message, usually placed in the response content, as part of the data
  • Data, depending on the interface protocol, may be in various formats, currently the most popular is JSON

We use the JSON form in practice, initially defining such a form

{
    "code": "number",
    "message": "string",
    "data": "any"
}

codeIt is mainly used to guide the front-end to perform some special operations, such as 0indicates that API call is successful, 非0indicates that the call fails, 1indicates that login is required, 2indicates that authorization is not obtained... For this definition, after the front-end gets the response, it can be done in the application framework layer. Conventional processing, for example, when codeis 1, a login window will pop up asking the user to log in on the current page, and when codeis 2, a message will pop up and a link will be attached to guide the user to obtain authorization.

See: Encapsulated Api Calls for Front and Back Separation Models

This was fine at first until the front-end framework switched to jQuery EasyUI. Many UI libraries such as EasyUI support configuring data URLs for components. It will automatically obtain data through AJAX, but it has requirements for data structure. If you still use the previously designed response structure, you need to define a data filter for the component to process the response result. In this way, the workload of writing a filter and declaring a filter for the component is not small. In order to reduce the workload of this part, we decided to change the interface.

The new interface is a mutable structure. Normally, it returns the data structure required by the UI. In the case of an error, it responds to a data structure of the original type:

{
    "error": {
        "identity": "special identity string",
        "code": "number",
        "message": "string",
        "data": "any"
    }
}

For the new response data structure, the front-end framework only needs to determine whether the errorattribute exists, and if so, check whether the identityattribute is a specified special value (such as a specific GUID), and then use its codeand messageattributes to handle errors. This error judgment process is slightly more complicated, but it can be handled uniformly by the front-end application framework.

If a RESTful interface is used, some status codes can be replaced by HTTP status codes. For example, 401 means login is required, 403 means not authorized, and 500 means an error occurred during program processing. Of course, while HTTP status codes are more compatible with the RESTful style, non-RESTful styles can also use HTTP status codes instead error.code.

User Authentication

There are many authentication schemes. For example, Cookie/Session is still feasible in some environments. You can also use Token-based and OAuth or JWT, or even implement your own Token-based authentication method.

Cookie/Session based authentication scheme

It is not infeasible to adopt the traditional Cookie/Session authentication scheme, but there are some limitations. If the front-end part and the back-end part have the same origin, for example, the page is published in http://domain.name/, and the Web API is published in http://domain.name/api/, in this case, the Cookie/Session solution used in the original integrated Web solution can be directly migrated without pressure. But if the front publishing and API publishing are different sources, this method is complicated to deal with.

Then, in the development method that separates the front and back ends, whether it is the development stage or the release stage, the possibility of different sources accounts for the vast majority, so the authentication scheme usually uses a scheme that has nothing to do with cookies.

OAuth based authentication scheme

At present, the open interfaces of major websites are all SOA architectures. If these open interfaces are regarded as service providers (servers), and the applications using these open interfaces are regarded as clients, then such a The relationship corresponding to the separation before and after:

前端 ⇌ 客户端
  (基于 OAuth 的认证)
后端 ⇌ 服务端

Therefore, the OAuth scheme widely used by the open interface is feasible for the separation of front and back, but it is not so easy to implement. Especially in terms of security, since the front end is completely exposed, compared with the environment where OAuth is usually implemented (backend⇌server), it should be noted that the first authentication does not use the registered AppID and AppToken, but the user. name and password.

Token/JWT-based authentication scheme

Although this solution is placed at the end, this solution is currently the most suitable solution for front-end and back-end separation. Token-based authentication schemes have been discussed for a long time, and JWT is a relatively mature one that has been recognized by most people. JWT implementations of various technology stacks can be found on jwt.io, which is also more convenient to apply .

Having said that, there is still a big difference between the JWT solution and the previously used Cookie/Session processing, which requires a certain learning cost. Some people worry that the data volume of the JWT is too large. This is indeed a problem, but the hardware is not expensive, and 4G has also begun to enter the stage of unlimited traffic. In general applications, you don't need to pay too much attention to this problem.

Test of front and rear separation

After the front and back are separated, the front-end testing will be mainly based on user experience testing and integration testing, while the back-end will mainly be unit testing and Web API interface testing. Compared with the integrated web application, there is an additional layer of interface testing, which can be fully automated. Once the test development is completed, business processing and data errors can be controlled to a large extent. In this way, the workload of integration testing will be relatively single and much easier.

The work of front-end testing is relatively not much relieved, and the front-end part after the separation of front and rear undertakes the original integration testing work. However, if the integration test is performed under the assumption that the Web API is correct, the workload can be reduced a lot, and the use case can only focus on front-end experiential issues, such as whether the rendering is correct, whether the jump is correct, whether the user's operation steps meet the requirements and Whether the prompt information is accurate and so on.

For user input validity validation, this part of the work can even be completely left to Web API to handle when the project time is tight. Regardless of whether the front-end and back-end are separated, there is a consensus in web development: never trust the front-end! Since the back-end must ensure the security and validity of the data, omitting this step in the front-end will not cause any substantial threat to the back-end. However, if both the front-end and the back-end need to verify the validity of the data, it must be done strictly according to the document, otherwise it is easy to have inconsistent data verification between the front-end and the back-end (this is not a problem of separation between the front and back, and the integrated architecture also has this problem).

summary

Overall, the benefits of front-to-back separation are obvious. However, a new way of thinking is required when implementing it, rather than thinking based on the original integrated Web development method. The open approach of separation between front and back frees developers from complex technology combinations, and everyone can focus more on their areas of expertise for development, but at the same time, it also puts forward higher requirements for communication between front-end and back-end teams. The team must work together to design a relatively stable Web API interface (in fact, this part of the work is indispensable regardless of whether the front-end and back-end are separated or not, but the front-end and back-end separation architecture requires higher requirements for this, and more clearly requires that the interface not only exists in human memory. , but also to document and persist).

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324535325&siteId=291194637