Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .github/styles/config/vocabularies/Docs/accept.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ bun
[cC]acheable
[cC]hatbot
[cC]lasspath
[cC]olspan
Codeium
[cC]onfig(|uration|ure|urer|urator|map)
[cC]onformant
Expand All @@ -42,6 +43,7 @@ Datadog
[dD]eclaratively
DeltaSpike
denylist
dev
deregister(ed|ing)
[dD]eserialization
[dD]estructuring
Expand Down Expand Up @@ -92,6 +94,7 @@ Hilla
Initializr
IntelliJ
[iI]nterdependencies
iText
[iI]terable
Jakarta EE
Jandex
Expand Down Expand Up @@ -141,11 +144,13 @@ Minifinder
[mM]ixin
MobX
[mM]odeless
[mM]odulith
[mM]onospace
[mM]ulticast
[mM]ultiplatform
[nN]amespace
[nN]avbar
NET
NetBeans
npm
npx
Expand All @@ -161,6 +166,8 @@ OpenAPI
[oO]verconsumption
pageable
[pP]asswordless
PDFBox
PDFs
Payara
performant
[pP]ersister
Expand Down Expand Up @@ -260,13 +267,15 @@ APIs
CDN
Cmd
DOM
DTOs
IDE
JDK
MVC
LLMs
PWA
RPC
SPI
SPIs
SSDs
SVG
UI
Expand Down
4 changes: 2 additions & 2 deletions articles/building-apps/ai/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ order: 69

= AI in Vaadin Applications

In this section, you'll learn how to connect a Vaadin application to a Large Language Model (LLM) and integrate AI features into your workflows. Using common Vaadin application scenarios as examples, you'll explore typical UI patterns for AI integration. The focus is on simple, adaptable examples that you can quickly implement in your own projects.
In this section, you learn how to connect a Vaadin application to a Large Language Model (LLM) and integrate AI features into your workflows. Using common Vaadin application scenarios as examples, you explore typical UI patterns for AI integration. The focus is on simple, adaptable examples that you can quickly implement in your own projects.

You'll learn how to:
You learn how to:

* connect your application to an AI client with popular Java libraries such as Spring AI and LangChain4j,
* choose Vaadin components that create intuitive, AI-powered workflows -- such as `MessageInput`, `MessageList`, and `Scroller`, and
Expand Down
18 changes: 9 additions & 9 deletions articles/building-apps/ai/quickstart-guide.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ section-nav: badge-flow
---


= Quick Start-Guide: Add an AI Chat Bot to a Vaadin + Spring Boot Application [badge-flow]#Flow#
= Quick Start-Guide: Add an AI Chatbot to a Vaadin + Spring Boot Application [badge-flow]#Flow#

This guide shows how to connect a Large Language Model (LLM) into a Vaadin application using Spring AI and Spring Boot. You'll build a minimal chat UI with Vaadin provided components **MessageList** and **MessageInput**, stream responses token-by-token, and keep a conversational tone in the dialog with the AI.
This guide shows how to connect a Large Language Model (LLM) into a Vaadin application using Spring AI and Spring Boot. You build a minimal chat UI with Vaadin provided components **MessageList** and **MessageInput**, stream responses token-by-token, and keep a conversational tone in the dialog with the AI.

image::images/chatbot-image.png[role=text-center]

Expand All @@ -20,7 +20,7 @@ image::images/chatbot-image.png[role=text-center]
== Prerequisites

* Java 17+
* Spring Boot 3.5+ (or newer)
* Spring Boot 3.5+
* Vaadin 24.8+
* An OpenAI API key (`OPENAI_API_KEY`)

Expand All @@ -31,7 +31,7 @@ Download a Vaadin Spring starter from http://github.com/vaadin/skeleton-starter-

**Pro Tip**: Starting the application with Hotswap Agent improves your development lifecycle.

Start with a cleaning and remove the default service `GreetService` and clear the existing UI content. You'll implement everything in `MainView`.
Start with a cleaning and remove the default service `GreetService` and clear the existing UI content. You implement everything in `MainView`.


== 2. Add Spring AI dependencies
Expand Down Expand Up @@ -72,7 +72,7 @@ Add the Spring AI BOM and the OpenAI starter to import the necessary dependencie

== 3. Configure Your OpenAI Credentials

To access the API of OpenAI you need a license key. The preferred way to provide the key is through an environment variable, as this makes it available to other applications as well. After setting the environment variable on your system, refer to it from `application.properties` like this:
To access the API of OpenAI you need an API key. The preferred way to provide the key is through an environment variable, as this makes it available to other applications as well. After setting the environment variable on your system, refer to it from `application.properties` like this:

[source,properties]
----
Expand All @@ -86,7 +86,7 @@ spring.ai.openai.api-key=${OPENAI_API_KEY}

== 4. Enable Vaadin Push

To prevent end-users from sitting in front of a blank screen waiting for a response, you'll stream tokens asynchronously and update the UI live with response tokens. To do this, you need to enable server push:
To prevent end-users from sitting in front of a blank screen waiting for a response, you stream tokens asynchronously and update the UI live with response tokens. To do this, you need to enable server push:

[source,java]
----
Expand Down Expand Up @@ -156,12 +156,12 @@ public class ChatService {

----

Why a chat memory? **ChatMemory** keeps context of the conversations so users don't have to repeat themselves. The `chatId` keeps the context for a specific chat and doesn't share it with other chats and users.
Why a chat memory? **ChatMemory** keeps context of the conversations so users do not have to repeat themselves. The `chatId` keeps the context for a specific chat and does not share it with other chats and users.


== 6. Build the Chat UI with Vaadin

Use `MessageList` to render the conversation as Markdown and `MessageInput` to handle the user prompts. Wrap the list in a `Scroller` so long chats don't grow the layout beyond the browser window:
Use `MessageList` to render the conversation as Markdown and `MessageInput` to handle the user prompts. Wrap the list in a `Scroller` so long chats do not grow the layout beyond the browser window:

[source,java]
----
Expand Down Expand Up @@ -281,4 +281,4 @@ Start the application, open the browser, and try your first prompts.
* `src/main/resources/application.properties` — OpenAI config
* `pom.xml` — Vaadin + Spring AI dependencies

That's it your Vaadin application now speaks AI. 🚀
That is it -- your Vaadin application now speaks AI.
2 changes: 1 addition & 1 deletion articles/building-apps/ai/technical-setup/ide/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ Never commit API keys to source control. Prefer environment variables or your CI

== IDE Quick Guides

If you're unsure how to set environment variables in your specific IDE, see:
If you are unsure how to set environment variables in your specific IDE, see:

* <<intellij#,IntelliJ IDEA>> (Ultimate or Community)
* <<vscode#,Visual Studio Code>>
Expand Down
2 changes: 1 addition & 1 deletion articles/building-apps/ai/technical-setup/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ Key characteristics:
Popular tools:

* https://ollama.com/[Ollama] - run many LLMs locally with a simple CLI and API.
* https://lmstudio.ai/[OpenLM Studio] - manage and run models locally with a graphical UI.
* https://lmstudio.ai/[LM Studio] - manage and run models locally with a graphical UI.


=== Quick Comparison
Expand Down
10 changes: 5 additions & 5 deletions articles/building-apps/architecture/api-spi.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,18 @@ order: 5

Whenever you design a building block for a Vaadin application - such as an application service or a UI component, you should think about how it interacts with the rest of the application. This typically happens through an *Application Programming Interface* (API), a *Service Provider Interface* (SPI), or a combination of both.

In this article, you'll learn what these mean, when to use them, and how to implement them in Java.
In this article, you learn what these mean, when to use them, and how to implement them in Java.


== Application Programming Interface

You typically design an API for either individual _classes_, or for entire _packages_. The API allows other parts of the application to _call_ your class or package. The other parts of the application depend on said class or package.

In this example, class B exposes an API that class A can call. Thus, class A depends on B and have to change if the API of class B changes:
In this example, class B exposes an API that class A can call. Thus, class A depends on B and has to change if the API of class B changes:

image::images/api-dependency.png[A diagram of package A and package B, where package A depends on package B]

In Java, the API of a class is its _public_ methods. The API of a package are the _public_ classes and interfaces. All classes or methods that are not considered a part of the API should have a different visibility than public, such as package private.
In Java, the API of a class is its _public_ methods. The API of a package is the _public_ classes and interfaces. All classes or methods that are not considered a part of the API should have a different visibility than public, such as package private.

In this example, `MyApplicationService` class is a part of the public API of the `com.example.application.service` package. The `publicApi()` method is a part of the public API of the class:

Expand Down Expand Up @@ -105,7 +105,7 @@ public class MyApplicationService {

=== The API is Optional

Not all classes and packages require a public API. For instance, a UI view is typically only called by the web browser. Therefore, it doesn't need an API at all.
Not all classes and packages require a public API. For instance, a UI view is typically only called by the web browser. Therefore, it does not need an API at all.


== Service Provider Interface
Expand All @@ -129,7 +129,7 @@ The end result would have been the same -- package B calls package C -- but now

As a rule of thumb, declare an SPI in the following cases:

1. *You don't yet know what the implementation is going to look like*. In this example, you can finish work on package B and use a mock implementation of the SPI until you start on the real implementation.
1. *You do not yet know what the implementation is going to look like*. In this example, you can finish work on package B and use a mock implementation of the SPI until you start on the real implementation.
image:images/spi-unknown.png[A diagram of packages A and B, where a question mark points to an SPI of B]

2. *You need to support multiple implementations*.
Expand Down
2 changes: 1 addition & 1 deletion articles/building-apps/architecture/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ section-nav: badge-deep-dive

.Deep Dive - Recommended Approach
[IMPORTANT]
This *opinionated* deep-dive explains core concepts (for example, architectural layers and monoliths) and gives a practical, recommended way to architect Vaadin applications. If you're new, this is a good place to start; if you're experienced, feel free to use whatever patterns work for you.
This *opinionated* deep-dive explains core concepts (for example, architectural layers and monoliths) and gives a practical, recommended way to architect Vaadin applications. If you are new, this is a good place to start; if you are experienced, feel free to use whatever patterns work for you.

section_outline::[]

8 changes: 4 additions & 4 deletions articles/building-apps/architecture/layers.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ order: 1

= Conceptual Layers

If you have any previous experience with software architectures, you have probably heard about layers. You may have run into terms like “presentation layer”, “business logic layer”, “infrastructure layer”, etc. Layers can help you reason about the structure of the application, but they can also impose unnecessary restrictions. For instance, if you require that a layer can only depend on the layers below it, you can't use Service Provider Interfaces (SPI). Because of this, you should focus on system components with clear <<api-spi#,APIs and SPIs>> rather than layers in your Vaadin applications.
If you have any previous experience with software architectures, you have probably heard about layers. You may have run into terms like “presentation layer”, “business logic layer”, “infrastructure layer”, etc. Layers can help you reason about the structure of the application, but they can also impose unnecessary restrictions. For instance, if you require that a layer can only depend on the layers below it, you cannot use Service Provider Interfaces (SPI). Because of this, you should focus on system components with clear <<api-spi#,APIs and SPIs>> rather than layers in your Vaadin applications.

That said, two layers make sense to use in Vaadin applications as well: the _UI layer_ (also known as the _presentation layer_) and the _application layer_.

Expand All @@ -20,10 +20,10 @@ In traditional web applications, you have the _frontend_ and the _backend_. The
[link=images/layers.png]
image::images/layers.png[A diagram illustrating the UI layer and application layer of a Flow and a Hilla app, respectively]

When you are building your user interface with Flow, you write the user interface in Java and run it on the server - the backend. Unless you have created any web components of your own, all the code that runs in the browser -- the frontend -- is provided by Vaadin in one way or the other. The frontend and backend don't map directly onto the user interface and business logic.
When you are building your user interface with Flow, you write the user interface in Java and run it on the server - the backend. Unless you have created any web components of your own, all the code that runs in the browser -- the frontend -- is provided by Vaadin in one way or the other. The frontend and backend do not map directly onto the user interface and business logic.

When you are building your user interface with Hilla, you write the user interface in React and run it in the browser. The rest of the application runs on the server. In this case, the frontend and backend correspond to the user interface and business logic.

It's also possible to write hybrid applications, where you write some parts of the user interface in Java and other parts in React. In this case, parts of the user interface run in the browser and parts on the server.
It is also possible to write hybrid applications, where you write some parts of the user interface in Java and other parts in React. In this case, parts of the user interface run in the browser and parts on the server.

Because of this, it makes more sense to talk about the UI layer and the application layer, as opposed to the frontend and the backend, or the user interface and the business logic. It's important to remember that these layers are _conceptual_ rather than physical. In a Flow or hybrid application, the UI layer covers both the browser and a part of the server. In a Hilla application, the UI layer is limited to the browser alone. In all cases, the application layer resides on the server.
Because of this, it makes more sense to talk about the UI layer and the application layer, as opposed to the frontend and the backend, or the user interface and the business logic. It is important to remember that these layers are _conceptual_ rather than physical. In a Flow or hybrid application, the UI layer covers both the browser and a part of the server. In a Hilla application, the UI layer is limited to the browser alone. In all cases, the application layer resides on the server.
Loading