I've recently come across Hilla, probably on Twitter, and decided to have a play around with it and find out what it does.
This article will serve as an introduction to Hilla.
Let's start.
What is Hilla?
Hilla is a web framework that uses Java Spring Boot for the backend, Lit library and Typescript for the frontend.
If you'd like to know more, I wrote an article on my blog about the Spring Boot Architecture.
Spring Boot is a Java backend framework that uses the Spring Framework internally.
Spring Boot makes it easier to bootstrap an application, and it's best used to create REST APIs.
Lit library instead
Lit is a simple library for building fast, lightweight web components.
At Lit's core is a boilerplate-killing component base class that provides reactive state, scoped styles, and a declarative template system that's tiny, fast and expressive.
I'm a backend engineer, so I had to inform myself about the definition of a web component.
According to webcomponents.org :
Web components are a set of web platform APIs that allow you to create new custom, reusable, encapsulated HTML tags to use in web pages and web apps.
A web component allows you to separate an application into smaller and reusable pieces.
Typescript is a programming language created and maintained by Microsoft.
Typescript is:
- strongly-typed.
- supports object-oriented programming.
- supports compilation.
Hilla allows you to build small and large enterprise-level applications.
Hilla has three main characteristics:
Type-safety: Hilla makes Java endpoints safe.
UI components: you won't have to create UI components yourself.
Speed and flexibility: Hilla uses Lit, a lightweight framework which helps you create components quickly and efficiently.
You can access Hilla's official documentation here.
1. ENVIRONMENT SETUP
If you (like me) have never used the Typescript ecosystem, you may have to do a few more installations than the one suggested in Hilla's Documentation.
You will need:
- Node 16.14 or higher.
- Vaadin.
- Lit.
- Typescript.
To install NodeJs, follow the official page.
To install the Vaadin CLI (a command-line interface to create Java web applications), run this command in your terminal:
npm i -g @vaadin/cli
To install Lit, run this command in your terminal:
npm i lit
To install Typescript, run this command in your terminal:
npm i -g typescript
2. CREATE THE APP VIA THE TERMINAL
To create a Hilla application, run this command in your terminal:
npx @vaadin/cli init --preset hilla-quickstart-tutorial hilla-student-app
It may or may not ask you to install @vaadin/cli
. If so, type y
.
Import the project into your IDE.
3. CREATE THE MODEL CLASS
Let's create a Student.java file under the src/main/java/com/example/application
directory.
The model class represents a Student object with a name, surname, and age.
package com.example.application;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
public class Student {
@NotBlank
private String name;
@NotBlank
private String surname;
@NotNull
@Min(value = 18)
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
4. CREATE A STUDENTENDPOINT CLASS
In backend engineering, an "endpoint" typically corresponds to a URL. It's the point that allows communication with another program.
Hilla guarantees type-safe access to the server.
package com.example.application;
import com.vaadin.flow.server.auth.AnonymousAllowed;
import dev.hilla.Endpoint;
import dev.hilla.Nonnull;
import java.util.ArrayList;
import java.util.List;
@Endpoint
@AnonymousAllowed
public class StudentEndpoint {
private final List<Student> studentList = new ArrayList<>();
public @Nonnull List<@Nonnull Student> getStudents() {
return studentList;
}
public Student saveStudent(Student student) {
studentList.add(student);
return student;
}
}
Note that the class has two annotations:
-
@endpoint
: this annotation makes the class accessible to the client. -
@anonymousallowed
: anyone can access this endpoint.
5. CREATE A REACTIVE UI IN TYPESCRIPT
In the frontend/views/student/student-view.ts
path, there should be a studentview.ts
file. If not, create one and paste the following code:
import '@vaadin/button';
import '@vaadin/text-field';
import '@vaadin/number-field';
import '@vaadin/grid/vaadin-grid';
import { html } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import { View } from '../../views/view';
import { Binder, field } from '@hilla/form';
import { getStudents, saveStudent } from 'Frontend/generated/StudentEndpoint';
import Student from 'Frontend/generated/com/example/application/Student';
import StudentModel from 'Frontend/generated/com/example/application/StudentModel';
@customElement('student-view')
export class StudentView extends View {
@state()
private students: Student[] = [];
private binder = new Binder(this, StudentModel);
render() {
return html`
<div class="padding: 25px">
<div>
<vaadin-text-field
${field(this.binder.model.name)}
label="Name">
</vaadin-text-field>
<vaadin-text-field
${field(this.binder.model.surname)}
label="Surname">
</vaadin-text-field>
<vaadin-number-field
${field(this.binder.model.age)}
has-controls
label="Age">
</vaadin-number-field>
<vaadin-button
theme="primary"
@click=${this.addStudent}
?disabled=${this.binder.invalid}>Add</vaadin-button>
</div>
<h3>Student List</h3>
<vaadin-grid .items="${this.students}" theme="row-stripes" style="max-width: 400px">
<vaadin-grid-column path="name"></vaadin-grid-column>
<vaadin-grid-column path="surname"></vaadin-grid-column>
<vaadin-grid-column path="age"></vaadin-grid-column>
</vaadin-grid>
</div>
`;
}
async addStudent() {
const students = await this.binder.submitTo(saveStudent);
if (students) {
this.students = [...this.students, students];
this.binder.clear();
}
}
async firstUpdated() {
const students = await getStudents();
this.students = students;
}
}
Note how this class has a couple of annotations:
@customElement
: this annotation registers the class (student-view) with the browser.@state
: the students' list is marked with@state
because it's subject to change.
6. RUN THE APPLICATION
Next, run the application.
It should automatically open in the browser, and you should see an app like this:
Add a name, surname, and age.
Then click the Add
button.
Notice that you're not allowed to add a student whose age is under 18:
When you run the application, you might get something such as:
Port XXXX is already in use.
To fix this:
Go into the
resources
folder and open theapplication.properties
file.Change the
server.port=${PORT:XXXX}
into another port. For example, if the error says that the port 8080 is already in use, change it to 8082 (or 8083, 8585, etc.).
CONCLUSION
In this tutorial, you learned how to create a basic Hilla application.
I hope you've found it helpful.
I'm learning Typescript from scratch, so let me know if you've spotted anything incorrect in the comments.
Until next time! 🙋🏾♀️
ADDITIONAL RESOURCES
Top comments (1)
I Loved the rebranding from Fusion to hilla, now it's easier to understand that is kinda separated from vaadin.
Anyways, I think that you may like JHipster.