📜 ⬆️ ⬇️

The interaction architecture of the client and server parts of the Web application

I wanted to tell you how I see the device architecture of the interaction between the server and client parts. And I would like to know to ask habrovchan, what is bad or good such architecture.



Client structure


Even outdated browsers offer us a set of features for creating rich interactive web applications. And thanks to such libraries as jQuery, which offer not modest cross-browser and multiplatform solutions, the development of client parts is accelerated many times over. Than webmasters use to the fullest, using a variety of interfaces for interaction between server and client parts.

Why jQuery? In this article, I use it just for example. For interaction between the client and server parts of applications, it does not matter what you use: any library, your own development or bare javascript. The main thing is to achieve the goal: for everything to work and work correctly.
')
Of course, many of us began the study of jquery with cycles of articles for beginners, introducing on our sites and dynamically loading content, and checking forms on the server side, and much more.

Over time, the size of the code has grown: there are a lot of response handlers from the server part in the project. Somewhere a whole page is requested and a piece of content is pulled out of it, somewhere there is a request for various files, somewhere JSON is expected, and XML is somewhere. All this needs to be cleaned up so that the code is smaller, and it works faster, and it is easier to work with it.

First of all. Create a single interface to send requests.
To do this, wrap $ .ajax into its own sugar function.

Of course, $ .ajax can be configured via $ .ajaxSetup. And it is more convenient and practical. But then there are several problems.

I prefer to wrap everything in a different function. It’s not so practical, and it generates more code, but it’s safer to use. Another programmer, seeing an unfamiliar function, will immediately pay attention to it. And, probably, having looked, as other request goes, will make also. And if they do not understand, then nothing will prevent the use of the standard $ .ajax function.

//
$.extend({
gajax: function (s) {
//
var options = {
url: "ajax.mysite.ru" ,
};
//
$.extend( options, s, { action:s.action } );
$.ajax( options );
}
});
//
$.gajax({
data: {
username: 'my_username'
},
action: 'do_something'
});

Secondly , it is necessary to reduce the number of entry points for AJAX requests. If the requests were sent both to index.php, and to request.pl, and to upload.xml, then this is a huge amount of work, and it often happens that it is impossible to do this without rewriting the entire server part again. Although this should be done if you want to quickly and simply expand the client part. Like all rules, it has exceptions. About them below.

Third, the most important thing : it is necessary to unify the response handler.

For example, in our project all ajax requests go only to the ajax.php file. It always returns some data in the form of XML, quite simply structured.

A single response handler parses XML and decomposes:

• A list of js-files that are required to process the response.
• Callback functions that must be run, and which arguments to these functions must be passed.
• Pieces of HTML code to be applied in the above functions.
• A list of css files that are needed to decorate html code.

//
$.extend({
gajax: function (s) {
var recognize = function ( xml, s ) {
/* , */
// xml ( jQuery XML, )
// js-,
// ,
// callback`
// html
};
//
var options = {
url: "ajax.mysite.ru" ,
success: function (xml){
recognize( xml, s );
}
};
$.extend( options, s, { action:s.action } );
$.ajax( options );
}
});



When everything is laid out, load the missing js-files. Perhaps one or more of the requested scripts have already been loaded previously loaded, so check it first. Validation methods depend on the general architecture of javascript code.

Then we load the styles. The mechanisms for loading scripts and styles are almost identical. Of course, styles are only needed when the data is displayed to the user, but by this point they should already be loaded.

When all scripts are loaded, we start callback functions.

It should be noted that to speed up the download, all js files are loaded asynchronously, and accordingly there may be a problem with the launch of callback functions. After all, they can be in these files.
The solution to this problem can be to create dependencies of functions on js files. This, in turn, causes problems for the programmer to control these dependencies and transfer them along with the response to the client side.
The second solution is to wait for the download of absolutely all the requested files and only then start executing the functions.
How to make it beautiful, you can listen to this wonderful podcast habrahabr.ru/blogs/hpodcasts/138522

I chose the simplest solution for my projects - the second one. I proceeded from the fact that loading the necessary js files is extremely rarely needed, because all the scripts on the server side are combined into packages. And usually the package contains all the necessary callbacks in advance. And if the file upload will be needed, it will require a maximum of one or two files, which will not delay the processing of the response.

Let me remind you that by this moment the user still does not see any changes on the screen. Well, we will show them them - we will begin to carry out functions. The main thing to consider is that all response handler functions must be independent of each other. They may depend on one large component (for example, the functions of the project core), but they do not have to be from each other. This will allow you to move and integrate callback and other parts of the project without any special problems. For example, displaying pop-up error messages may be required on all pages.

Functions completed, the user works on.

Processing requests by the server


Now I would like to make out a situation when a request was sent that the server could not make out for some reason.

With us, all requests are not only sent to one file, but all data in it is sent using the POST method. On the server side, some “action” POST parameter is expected. The value of this parameter determines which module of the site should work. The pairs themselves with the expected values ​​and names of the modules are written in the configuration file. If there is a corresponding module in the configuration - it is launched, if not - the default module is started, which is configured to return an error message.
Also, we can write all the request parameters to the server log. Analysis of the log then allows you to quickly track and correct the error. Or, during the execution of the script, ban the user's IP for about 15 minutes for searching the values, if there is confidence that there are no errors in our application. But this is extreme.

Processing erroneous requests on the client side


We must not forget about the processing of failed requests, for example, by timeout or the sudden disconnection of the user from the network.

//
var options = {
url: "ajax.mysite.ru" ,
success: function (xml){
recognize( xml, s );
},
error: function ( s,err ){
//
if ( s.status == 200 && err == 'parsererror' ) {
alert( s.responseText );
}
//
else if ( err == 'timeout' ) {
alert( 'Connection to the server was reset on timeout.' );
}
// - .
else if ( s.status == 12029 || s.status == 0 ) {
alert( 'No connection with network.' );
}
};


Caching


Let's return to the question about entry points. From the point of view of writing beautiful code, specifying only one address for an entry point is not an entirely correct solution. This is by no means contrary to my second advice. I will try to make out all sides of this issue.

How could one make everything beautiful? - Send requests to specific addresses. For example, ajax.php? Action = feedback or ajax.example.com/feedback. This would save the request from unnecessary garbage. When a module is defined that will process the data, it no longer needs this information. Flies separately, cutlets separately. Handsomely? Handsomely.

If there are no POST parameters in the request at all, then this is a good opportunity to use caching features on intermediate proxies or browser caches.
A recommendation from Google for webmasters says that the lack of GET parameters in the http request provokes the proxy server to use the cache. Therefore, a request without POST and GET parameters, for example ajax.mysite.com/footer, would be ideal for adding it to the proxy cache server. Of the additional advantages, I note that if the answer comes from a proxy server, then our server will also be a little unloaded.
When it may even need? When we load parts of the page via ajax. However, they are unchanged for a long time.

But it is not necessary to use an ajax request without a GET or POST parameter, since there is a possibility of receiving non-actual data.
Suppose we have a chat and we do not use web sockets. Every second we go to the server to see new messages. The user is caught for some proxy server. The first request will succeed and return that there are no messages. For all subsequent requests, the proxy server will return the initial response. And it will disrupt the entire work of the chat. Problems can be avoided by adding a parameter to the query. That, in turn, will create the very garbage that we have tried so hard to avoid.

In matters of caching, each time you need to approach individually and use what is necessary for the project.

Inventing a bicycle


In our project, the data in the request is sent only by the POST method, because the caching mechanism we have laid in that very unified interface for sending ajax requests. By default, absolutely every request and response to it is remembered for 3600 seconds. In a subsequent similar request, the cache will work, take the answer from the box and launch all the mechanisms for analyzing it at once, without sending a direct request to the server. After all, we are sure that all styles and scripts are already in place.
If you don’t need to remember the request-response pair, or simply reduce the cache lifetime, the server side reports this in the initial response, changing the cache time to 0 or a different number of seconds.

Why only POST, but not the combined option? It's easier to compare queries.
The data sent via the ajax function in jQuery is a js object.
The requested data is rather quickly compared with the objects in the cache, of course, if the client has a modern browser. If the browser is old, you have to forcibly disable the cache.

Eventually


As a result, we get a stable working bunch of client and server parts. And this bundle allows us to create safe and easy to further expand Web applications.

The post is written in the name of saving nanoseconds and a variety of nerve cells of programmers who create their beautiful creations.

Source: https://habr.com/ru/post/141467/


All Articles