Vaadin, the battery-included server-side AJAX framework

Nicolas Fränkel - Oct 17 - - Dev Community

I've written a lot about Vaadin. I was so enthusiastic that I wrote the first book about it (besides the Book of Vaadin), its updated edition for Vaadin 7, and a companion website. Still, I'm amazed that so many people in the JVM world never heard of it.

In this post, I'd like to introduce Vaadin in the context of AJAX and SSR.

Short introduction to Vaadin

The beauty of Vaadin lies in its simplicity - you only write backend code. You read that well. A Vaadin developer only needs to know Java, or any JVM language, and the Vaadin API. At runtime, Vaadin will create the client-side code, i.e., HTML, JavaScript and CSS. This approach empowers developers to focus on the application's core functionality, making the development process more productive.

Vaadin builds upon components and layouts, just like regular desktop-based frameworks do. If you know Swing or JavaFX, you will feel right at home.

I mentioned CSS above: Vaadin allows you to develop your CSS in a dedicated reusable package called a theme. The icing on the cake: developing a theme can be done in parallel to backend development and has no adherence to the latter; the code doesn't need to use a specific template or to add specific classes to the HTML.

Vaadin setup

Setting up Vaadin in the context of Spring Boot is a breeze:

<project>
    <properties>
        <java.version>17</java.version>
        <kotlin.version>1.9.24</kotlin.version>
        <vaadin.version>24.4.9</vaadin.version>                   <!--1-->
    </properties>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.vaadin</groupId>
                <artifactId>vaadin-bom</artifactId>               <!--2-->
                <version>${vaadin.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.vaadin</groupId>
            <artifactId>vaadin-spring-boot-starter</artifactId>   <!--3-->
        </dependency>
</project>
Enter fullscreen mode Exit fullscreen mode
  1. Set Vaadin version along with other properties
  2. Keep the version of all dependencies consistent
  3. Add the Vaadin Spring Boot integration library

Vaadin builds upon a regular Java Servlet, which maps to the root by default. The Vaadin Spring Boot integration allows overriding the default. Because our codebase integrates multiple frameworks, we map it to /vaadin via the relevant property:

vaadin.url-mapping=/vaadin/*
Enter fullscreen mode Exit fullscreen mode

At the first request from a client, Vaadin will return the JavaScript engine's code. The engine will make subsequent requests to retrieve the configured UI and scaffold the latter client side. From then on, the engine handles all user interactions and updates the UI if necessary.

First steps with Vaadin

Once we set up the project, we must configure which component Vaadin displays when it receives a request.

@Route("/")                                                       //1
@PageTitle("Vaadin")                                              //2
class TodoView(todos: ArrayList<Todo>) : VerticalLayout() {       //3-4-5

    init {                                                        //6
        // ...                                                    //7
    }
}
Enter fullscreen mode Exit fullscreen mode
  1. Associates the component to the Vaadin servlet subcontext root
  2. Set the static page title. In case you need a dynamic title, you can implement HasDynamicTitle
  3. Define a RootComponent class
  4. VerticalLayout is a class that Vaadin renders as an HTML div
  5. The Vaadin Spring Boot starter takes care of injecting the list
  6. Vaadin executes the init() function at the first browser request
  7. The next code snippets will go there

Adding components

In the above snippet, we inherited from VerticalLayout, a Vaadin-provided component.

The Vaadin Design System includes a set of components that you can use to build your UI. The components have a server-side Java API in addition to the TypeScript API for client-side development.

You use a component by first creating it and then adding it to a containing layout.

-- Creating UI in Vaadin Applications

Some components can contain others, and they know how to lay their subcomponents out. For example, VerticalLayout places components top-to-bottom in a column; HorizontalLayout places them left-to-right in a row.

Adding components to a layout is straightforward:

add(Label("Hello"))                                               //1
add(Label("world!"))
Enter fullscreen mode Exit fullscreen mode
  1. In the context of the init() function

While this works perfectly, we can improve the situation using Karibu-DSL since we use Kotlin. We can rewrite the above snippet as follows:

label("Hello")                                                    //1
label("world!")
Enter fullscreen mode Exit fullscreen mode
  1. label() is a Karibu DSL extension function on the HasComponent interface

Karibu is great, but with a slight downside: it doesn't offer extension functions for the whole API. For example, you need to fall back to the regular API to add footer to a Grid component:

appendFooterRow().apply {
    getCell(completedProp).component = Button("Clean up") {
        todos.removeIf { it.completed }
        refresh()
    }
}
Enter fullscreen mode Exit fullscreen mode

On the plus side, Karibu is Open Source, and you can always contribute if you have something to add.

Specific components related to the UI are not important for the general understanding. If you're interested, you can always check the source code.

User interactions

When mainframes were the kings of computing, you accessed them via terminals. The UI was pretty limited, and rendering occurred on the "dumb" terminal. Personal computers moved the rendering functionality from the server to the client. At this time, developers attached behaviour to a component via a trigger. For example, you could bind printing Hello world! when the user clicks a button.

Web applications changed this paradigm. As our previous articles showed, every interaction maps now to a request-response flow, synchronous or asynchronous. Vaadin brings us back to the original paradigm.

Checkbox(todo.completed).apply {                                  //1
    addValueChangeListener { todo.completed = it.value }          //2
}
Enter fullscreen mode Exit fullscreen mode
  1. Initialize a new Checkbox component with a value
  2. When the value of the checkbox changes, execute the lambda - we change the underlying model's value

There's no need for JavaScript code; Vaadin manages the interaction independently.

Conclusion

The post was but a short introduction to Vaadin in the context of AJAX and SSR.

Most developers who learn programming on web apps and are thus used to the request-response model react poorly when exposed to Vaadin. Their main argument is the absence of API. IMHO, it's a benefit: some apps, particularly business apps, don't evolve to the point where you'll need to develop dedicated mobile clients.

Vaadin comes with a default CSS set, as stated in the introduction. This default theme ensures Vaadin applications look good from the start, providing users with a comfortable and visually appealing work environment. However, you can always integrate another or even develop your own.

The real benefit, however, is found again at the organizational level. In the introductory post, I mentioned that separating frontend and backend development creates issues during their integration. Because Vaadin does not have such a separation, project planning is more predictable, as there is no integration step between the front end and back end. Likewise, theming can happen in parallel to development.

The complete source code for this post can be found on GitHub:

GitHub logo ajavageek / compare-frontends

Demo code for the series on AJAX and SSR

To go further:


Originally published at A Java Geek on October 13th, 2024

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .