ZK 10 Stateless components preview

From Documentation


DocumentationMattZK 10 Stateless components preview
ZK 10 Stateless components preview

Author
Matthieu Duchemin, Engineer, Potix Corporation
Date
July 13, 2022
Version
ZK 10 CE, PE, and EE

Introduction

ZK 10 introduces Stateless IComponents. In this smalltalk, we will discuss the use case for these components, as well as how to implement a document using them.

This is a follow-up on the previous ZK10 Preview smalltalk.

Overview

First, we need to understand the differences between classic ZK components, and the new Stateless components.

Classic ZK overview

Classic ZK components are stored in the HttpSession at server side. Based on the Java EE Web application specification. The session is an object which exist in memory at server side. When a web browser sends a request to the server, it also sends a session identifier. This is commonly done with a JSESSIONID cookie, or through a url parameter.

Based on this identifier, the Web Server will retrieve the session object from memory, and make it available while processing the response to the user's request. This allow the server-side application to store various objects semi-permanently in the server's memory, until the session is destroyed.

In the classic use case, the page generated by ZK exists in the session. When the user trigger an action, or change the state of a component at client-side, a request is sent to the server, and updates the "main state" of the components which exists in the session. In this workflow, the server-side state is authoritative, and the client-state is synchronized based on the server-side state.

Stateless components overview

The stateless components are not stored in the server's memory. They are transient objects which only exist during the user's request and response cycle.

In this case, the authoritative state is located at client-side. Updates performed with Stateless components are done on a "per action" basis.

Each action has a set of "Action parameters" which indicates what data needs to be retrieved from the client in order to process a given action. This way, no server-side record of the page's state is required. When the user triggers an action, the client-side engine will fetch the properties and values requested by the action, and sends all relevant data in the request.

The server-side action will then process any relevant update based on that data, and the event triggered by the user. At the end of that processing, the action may modify the state of the client, and send a response which will write the new state at client-side.

During this process, the action only used the information retrieved by the action parameters. As such, it did not need to access any data located at server-side.

Use cases and general questions

Stateless use cases

The main point of a page generated by the ZK 10 Stateless components is that it doesn't have an associated user session.

This is beneficial in a number of scenarios in which session access, session control and session replication are difficult.

Arbitrary containers

Let's consider an application using a platform such as docker, or manually instantiated and terminated copies of the same services such as spring boot.

Establishing session replication, sticky session (request priority given to the same node having processed the previous request by the same actor, if it is still available) and session failover can be challenging.

Since a page created with Stateless components doesn't rely on the user session to store the state of the components, the infrastructure can be simplified by not implementing these aspects.

Limited server-side memory per user

Some platforms have a limited user session size, or provide a serialized shared session object between all server nodes with a limited size. The Stateless components workflow is a good candidate for such infrastructures, since it doesn't rely on session, and doesn't keep object in memory between transactions.

Event outside of a cloud platform, the same low-memory footprint can be useful for a classically deployed application.

Composed page from multiple services

While a page can be composed from documents generated by both classic ZK and stateless components, the stateless components are a good fit for smaller scales "input and output only" services with a limited scope.

Are Stateless component an upgrade to classic ZK components

No. Stateless components are a branching technology from the classic ZK components. They use the same client-side code (the JavaScript Widgets and associated HTML and CSS code), in addition to a completely different communication and update layer.

How to handle use cases which require server-side permanence

While the Stateless components only exist during request and responses, you may need to store data which the user should not be able to modify, or data that should not be publicly accessible.

In this situation, some sort of shared permanence layer is necessary for the application's function. For this purpose, a good option is to use a database layer. In the stateless components demo application, the content of the user's shopping basket is stored in a SQL database. Since the data layer is decoupled from the web container, it can be accessed by any number of instances. Databases already provide replication and high availability features, which makes them a great candidate to act as the shared permanence layer.

I have an existing ZK application...

... using classic ZK, do I need to update my code to use Stateless component instead?

Maybe, maybe not. We do not see the Stateless component as "the next step" in ZK innovation. Instead, we see them as a convenient tool which can be used if they are relevant to a specific application's architecture requirements.

As a rule of thumb, consider the following.

I should use stateless components if:

  • I'm developing an application for an heavily distributed infrastructure in which session replication between nodes is difficult to achieve (cloud hosting, high availability with multiple regional clusters, etc.)
  • I'm developing smaller-scale services which do not need to know about each-other to perform their functions.
  • I do not have access to sticky sessions, which causes the active node for a given user to change with each request

I should use classic ZK if:

  • I already have a fully functional application, which matches my infrastructure needs
  • My infrastructure is a classic "Database, webserver (or webserver cluster), gateway/reverse proxy"
  • I need to store multiple data, states and other semi-permanent objects between requests
  • My application has a lot of interdependent systems which rely on server-side communication

Can stateless components and classic components be used in the same page?

Stateless and classic components cannot be used in the same document. The basic architecture for these components is different.

This said, a page can be created by composing content from multiple services. Nothing prevent some of these services from using stateless components, and others classic components.

Comparing and contrasting the Stateless workflow, and the new ZK 10 Client-MVVM features

Both of these new features have the goal of improving the resource footprint of a given page at server-side. There is a similar concept between both features: removing server-side component instances.

In the case of Client-side MVVM, the ClientBindComposer will keep track of the bindings and commands, but not create corresponding ZK components (the textboxes, grids, buttons, etc) in server memory.

The view model being already decoupled from the view doesn't need to know that the command comes from a server-side Java instance of Textbox, or if it was sent by the client, and forwarded directly by the ClientBindComposer. In the opposite direction, the client-side Textbox JavaScript object doesn't know if the update returned by the response is generated by a server-side Java Textbox object, or forwarded directly from the view model by the ClientBindComposer.

In the case of stateless components, the Java-side objects are also removed. Instead of maintaining a state in the view model, and using the ClientBindComposer to forward that state to the client-side objects, the stateless workflow use a list of inputs and outputs for each user action, in a pattern which is closer to MVC.

When a user trigger an action at client-side, all of the state data required to process that action is sent together with the request. As a result, there is no state at all located in server memory.

Stateless richlet

The | demo richlet provide in the ZK10 Preview smalltalk already shows how to setup a full page using the stateless components, register actions and perform updates.

For a very simple example of how a page and action declaration work with a stateless richlet, you can also refer to the | simple richlet demo sample.