Architectural overview
A high level overview of the system architecture
This diagram shows the architecture of KSS. (Click on it to view in full size.) We used the colors magenta, and yellow to mark the two different types of plugins, and the color red to mark the controlling information that governs the actual AJAX functionality.
The
entire process can be best characterized by overviewing the complete
flow of events of an AJAX action. First of all, all actions are
triggered from the client browser, by browser events. These are
the same that the programmer normally would bind to javascript
functions. Some of these events are generated by the user's interaction
(clicking on the page, etc) or are triggered in some other way (e.g.
timer events). Normally there would be some javascript code in the page
that must handle these events: in AZAX the events are handled by event binder plugins. These plugins control both how the event is bound and the actual process that executes when the event is triggered.
There are various event binder plugins
that come builtin by the AZAX system: the most simple plugin (called "native") binds to a
simple browser event via a CSS selector. There
are more event type plugins available and it is also possible to extend the
system by writing a custom event binder plugin, such event binder plugins can even
bind to more browser events and perform more complex functionality. The
way of binding these event plugins to browser events is specified by
the KSS resource file, this is a static resource file that accompanies the HTML page. The format of this resource is called KSS which is similar to CSS in syntax and nature, only it binds the dynamic behaviour to a page.
The binding code of the event binder plugins is run at page loading time. The event binder plugins may also specify the code to be executed when the event is triggered, but in most of the cases they simply pass execution to the eventrule action dispatcher. This uses the setup in the KSS rule to decide what action should be taken. The action is usually a server action, in which case controll will be passed to the server. It is also possible to execute client actions which execute locally, a typical example is to support debugging. It is also possible to execute more actions for the same event.
If an event triggers a server action, control will be passed thtough the request/response queue, which is a way to control the sending of events in the form of XMLHttpRequests to the server. The main task of the request/response queue is to limit the maximum number of the pending requests towards the server, and also perform error and timeout handling of requests. This functionality should really be carried out by the XMLHttpRequest stack itself but at the moment this requirement is not fulfilled by the browser implementations, hence the need for a separate layer.
Once the XMLHttpRequests are sent out they arrive on the server as special URL requests. One server action is designated to reply to each one of these requests. On Zope, this will incarnate method calls on the server. The methods will do whatever their designated task is, and as a result, they will command the client to do something in return. This is a principal point of AZAX: at this moment the server actions will decide what should happen on the clientThe server side event handlers do this by assembling a sequence of commands with parameters. This command calling sequence will be sent back to the client as a response.
The commands consist of a selector (typically) and a client action that will be called with parameters. When the command marshaller receives this sequence of commands, it will simply looks up the nodes selected by the selector and calls the assigned client actions on each of them in the required order, all with the parameters supplied by the server. The client actions act as callback functions: all they do is to carry out some task as a response to the original browser event that triggered out this action at first. Usually, the mission of the client action plugins is to manipulate the DOM of the browser page to transform it in a requred way. This, becoming visible for the user finishes the entire AJAX cycle that was started by the user and now he can see the result of his action.
The local actions, like the event binders, are builtin
to the AZAX system. The simplest and also most useful local action (appendInnerHTML)
simply replaces a selected tag in the DOM with a string value supplied
by the server as a parameter of the command. This covers the most
important AZAX use case: in return to some user action, the browser
simply replaces part of the page that is completely rendered on the
server side. Doing this results in a thin browser client where
most tasks are delegated to the server; and in a lot of AJAX use cases
this is also the most proper solution to be applied. But there are also
more local actions supplied for carrying out other common tasks, and
it is also possible to implement more complex actions as extensions
to the system. In the more complex cases it is probable that the server
will return a set of data that will be turned into more complex DOM
manipulation by the accompanying command plugin.
The principal characteristics of the process are these:
- All process control is embedded into the azax resource file (that decided how to bind browser events to the plugins, and how to dispatch them to the server), and server action code (that decides what commands to marshall in return). The application control logic is thus not implemented on the client side but is in the responsibility of the server.
- All javascript code (apart from the kukit core) is either an event binder plugin or a client action plugin, apart from this there is no javascript code appearing in the system. Most particularly, no javascript will ever appear in the html pages or in the skins.
This leads to a two-level component architecture:
first there are a set of event binders and actions providing
the base components that can carry out any task, and there is the
process control level that specifies how these should connect to each
other. The process control level is analogical to a program written in
a higher level programming language that specify what you want to carry out (the design) and the plugins are analogical to the instructions of this language that specify how each programming instruction should be done (the implementation). This makes it easy to separate design from implementation and also opens the was towards rapid prototyping
that means that you can start with implementing a thin client solution
by using the builtin set of plugins and if it becomes necessary can
gradually fatten your client by developing new custom plugins. The
latter one will naturally require javascript programming but even in
this case the result will be a well componentized implementation where
the details are totally decoupled from the level of the skin design.