โ๐ต๐ถ๐ผ๐บ๐ธ๐น๐ท
This is a Vaadin example application. A full-stack app: uses the H2 database instead of a dummy service; uses JOOQ to access the database. Requires Java 21+. Does not run on Spring.
The Starter demonstrates the core Vaadin Flow concepts:
- Building UIs in Kotlin with components
such as
TextField
,Button
,ComboBox
,DatePicker
,VerticalLayout
andGrid
(seeCategoriesList
) - Creating forms with
Binder
(ReviewEditorDialog
) - Making reusable Components on server side with
KComposite
(AbstractEditorDialog
) - Creating Navigation with the Router API (
MainLayout
,ReviewsList
,CategoriesList
) - Browserless testing: see the test suite package for the complete test implementation.
On top of that, a very simple way of using JOOQ is demoed:
- Running the
db {}
function runs the block in a transaction. Pure simplicity :) db
gives you access toDSLContext
, so you can simply calldb { create.selectFrom(CATEGORY) ... }
db { CategoryRecord(name = "Foo").attach().store() }
creates a new record in a database - the record is attached to the current transaction, enablingstore()
,delete()
and other JOOQ record functions.CATEGORY.dao.findByName("Foo")
demoes the ability to write DAOs with useful finder methods.
On top of that, the JOOQ-Vaadin integration is demoed as well:
- See the
CategoryRowDataProvider
on how to return the outcome of a JOIN statement from Vaadin'sDataProvider
; - See
JooqRecordDataProvider
for a generic DataProvider returning instances of any Record. Very handy for using in combination with aComboBox<CategoryRecord>
, seeReviewEditorForm
for more details.
This version of Beverage Buddy demoes the possibility of developing a Vaadin web application purely server-side in the Kotlin language. There is no JavaScript code in this project. We use Vaadin to avoid touching JavaScript after all.
See the online demo.
Run Main.kt
main()
function from your IDE, or run via ./gradlew run
.
Please see the Vaadin Boot documentation on how you run, develop and package this Vaadin-Boot-based app.
Without the database, we could store the categories and reviews into session only, which would then be gone when the server rebooted. We will use the JOOQ library to ease access to the SQL. To make things easy we'll use in-memory H2 database which will be gone when the server is rebooted - touche :-D
We will use Flyway for database migration. Check out Bootstrap.kt on how the migration scripts are ran when the app is initialized.
JOOQ records are generated in the com.vaadin.starter.beveragebuddy.backend.jooq
package, including the CategoryRecord
and ReviewRecord
. See JooqGenerator
on how to
generate the records. There are no DTOs - the records are passed around in the app and edited directly in the forms.
The records therefore contain jakarta.validation annotations to validate user input.
Careful when re-generating records, since those annotations will be lost.
The simplejooq package contains useful functions to access database without Spring:
- The
db{}
function runs given block in a transaction. You can't go simpler than that. - The
DAO
collection of extension functions, allowing you to writeCATEGORY.dao.getById()
and similar. - Validations
See the beverage-buddy-vok version for an example app using the jdbi-orm framework underneath.
Advantages of jdbi-orm:
- No generated classes. You write the entities yourself, with any utility functions you need. No generator is going to overwrite those.
- You can override built-in methods, e.g.
delete()
, to perform additional cleanup (e.g. set foreign keys to null) - Validation baked in and enabled by default: the entities are validated before they're saved or created.
Disadvantages:
- No generated classes - you need to write the entity classes yourself. However, you only need to do that once.
- Very little support for writing SELECTs from Java code. You write those as Strings instead.