ZK10 Preview: ZK 10 is ready for building Cloud-Native Applications

From Documentation


DocumentationSmall Talks2022AprilZK10 Preview: ZK 10 is ready for building Cloud-Native Applications
ZK10 Preview: ZK 10 is ready for building Cloud-Native Applications

Author
Katherine Lin, Engineer, Potix Corporation
Date
Apr. 19, 2022
Version
ZK 10

Introduction

Cloud-Native Application Development is an approach for applications to be designed, built, and optimized to run in the cloud. It has gained more and more attention as it provides an easy way to enhance scalability, availability, resource management, and auto-provisioning.

With ZK 9 or an earlier version, it is possible to run ZK in the cloud using the "sticky session" configuration, forcing all future requests for the same session to be sent to the same server. However, to be truly cloud-ready and maximize the use of cloud resources, starting from ZK 10, we will provide a new set of Java API and stateless components.

This article will discuss how you can use ZK 10's stateless components to build a cloud-native application and enjoy the benefits mentioned above. Also, the architectural change results in better performance and memory use.

We assume you already know the basics of ZK and could-native computing; we won't introduce cloud-native computing in detail here.

Demonstration: Shopping cart

We will take the shopping cart as an example, with the following architecture:

ZK 10 provide stateless components to support Cloud-native Application.

In this example, we use a containerized NGINX as the load balancer and Docker to run several decoupled ZK servers to simulate different nodes in a clustered environment.

As you can see in the video, each action (each ZK au request) is handled by a different server. This means ZK no longer requires requests in the same session to be sent to the same server. They can be processed from any clustered node. This also means you can fully leverage cloud resources in a more dynamic and resilient manner, and achieve autoscaling and high availability much easier.

Next, we will go through the process of building a ZK 10 application using stateless components.

Include Required Jar

ZK provides stateless components in a separate module, you need to include it explicitly first.

dependencies {
	implementation "org.zkoss.zk:stateless:${zkVersion}"
...
}

Check EE Evaluation repository or premium repository for the latest ZK 10 version.

Dispatcher Richlet Filter

We start from defining the Dispatcher Richlet Filter in WEB-INF/web.xml

 1 	<filter>
 2 		<filter-name>DispatcherRichletFilter</filter-name>
 3 		<filter-class>org.zkoss.stateless.ui.http.DispatcherRichletFilter</filter-class>
 4 		<init-param>
 5 			<param-name>basePackages</param-name>
 6 			<param-value><!-- your base packages --></param-value>
 7 		</init-param>
 8 	</filter>
 9 
10 	<filter-mapping>
11 		<filter-name>DispatcherRichletFilter</filter-name>
12 		<url-pattern>/*</url-pattern>
13 	</filter-mapping>
  • Line 6: specified the package having all your Richlets

Restful URL Mapping

In ZK 10, URL mapping is similar to using RESTful API. We use @RichletMapping to represent mapping the HTTP Request path with the GET method.

  • for example, the shoppingCart() URL will be <protocal>:// <host name: port> /shoppingCart.
    @RichletMapping("/shoppingCart")
    public class DemoRichlet implements StatelessRichlet {
        @RichletMapping("")
        public List<IComponent> shoppingCart() {
            //return ...
        }
    }

Composing the UI with Stateless Components

Before ZK 10, ZK components are stateful, meaning that the server holds the state. Starting from ZK 10, we provide a set of stateless components as Immutable objects. Immutable objects are constructed once and can not be changed after they are constructed. After Immutable objects are rendered, they will be destroyed. Since the component state will not be saved on the server, they consume less memory.

UI Composing

With ZK 10 stateless components, you will no longer write a zul file. You will be composing your view using the stateless components and their APIs in Java.

  • ZK component having a prefix letter "I" represents an immutable component.
  • We offer of() API for commonly used properties.
  • withSclass() means the setter of sclass.
    // ZK 10
    IButton.of("add items")
           .withSclass("add-items");
    // ZK 9
    // equivalent idea as above.
    Button button = new Button("add items");
    button.setSclass("add-items");

Event Wiring

To wire an event listener, you need to declare the ActionHandler method, with an annotation @Action.

  • The method should be public.
  • The parameter of @Action should be one of event types.
  • Wire the action handler with the target component by withAction(ActionHandler action).
    // ActionHandler method
    @Action(type = Events.ON_CLICK) // Wiring event
    public void addItem() {
        ...
    }

    public IComponent demo() {
         return IButton.of("add items").withSclass("add-items")
                .withAction(this::addItem);
    }

Obtain Widget State

Since a server no longer holds a component's state, we provide @ActionVariable to access component attributes and state sent from the client.

  • @ActionVariable(targetId = ActionTarget.SELF, field = "id") retrieves the value from the field of a component with the targetId on the client.
  • ActionTarget.SELF means it targets the component associates to the event itself.
    @Action(type = Events.ON_CLICK)
    public void addItem(@ActionVariable(targetId = ActionTarget.SELF, field = "id") String orderId) {
    }

Update Widget State

To update the widget state, we provide several APIs in UiAgent. The state will be updated to the client immediately.

  • The following example will add the specified child component as the last child to the locator.
    @Action(type = Events.ON_CLICK)
    public void addItem(@ActionVariable(targetId = SELF, field = "id") String orderId) {
        UiAgent.getCurrent().appendChild(Locator.ofId("shoppingBagRows"), addShoppingBagItem(parseUuid(orderId)));
    }

Conclusion

In this article, I have briefly introduced how you can use ZK 10's stateless components to build a could-native application to enjoy scalability, auto-provisioning, boosted performance, and reduced memory. This architectural change also increases the modularity and allows you to easily bridge with other modern applications and microservices.

We welcome you to download ZK 10 Freshly and build your first cloud-native application today!

Note. Stateless Component is a new feature in ZK 10 providing lighter and faster experiences and a cloud-friendly architecture. If you are not ready, you can still use ZK 10 in the same way as you usually do.

Download

You can download the shopping cart demo project from here.

ZK: use 10.0.0.FL.20230911 or later

For more ZK 10 articles, visit here.


Comments



Copyright © Potix Corporation. This article is licensed under GNU Free Documentation License.