Skip to content

Simple htmx project using spring boot with thymeleaf as backend

Notifications You must be signed in to change notification settings

sombriks/sample-htmx-spring

Repository files navigation

Java CI with Maven

Java CI with Gradle

Java CI with bld

Simple htmx project using spring boot with thymeleaf as backend.

Generated by spring initializr.

See HELP.md for further details.

Requirements

  • maven 3.9
  • java 17
  • htmx 2.0 (webjar)
  • spring 3.2 with webflux

How to build

./mvnw clean package

How to test

./mvnw test

How to run

./mvnw spring-boot:run

Or:

java -jar target/sample-htmx-spring-0.0.1-SNAPSHOT.jar

Noteworthy

  • Used functional endpoints instead of traditional web mvc to make this sample more similar to the other ones.
  • RouterFunctions demands specific routes to be declared first, this is why the configuration function looks slightly different from its kotlin and node counterparts.
  • Spring webflux is built on top of project reactor and demands a functional thinking way, therefore the difference in controller code.
  • Spring repositories are a formidable abstraction.
  • Liquibase defaults in spring configuration renders a broken project because it does assume a root changelog but it does not assume the changelog format.
  • Thymeleaf is a little picky regarding the templates "includes".
  • Added additional java build tooling, so we can compare maven, gradle and bld. It's a nice comparison and all three tools can produce a valid spring boot jar.

Benchmark results

The following results for the same test applied against the other versions.

 

          /\      |‾‾| /‾‾/   /‾‾/   
     /\  /  \     |  |/  /   /  /    
    /  \/    \    |     (   /   ‾‾\  
   /          \   |  |\  \ |  (‾)  | 
  / __________ \  |__| \__\ \_____/ .io

     execution: local
        script: benchmark-javalin.js
        output: -

     scenarios: (100.00%) 1 scenario, 10 max VUs, 1m0s max duration (incl. graceful stop):
              * default: 10 looping VUs for 30s (gracefulStop: 30s)


     ✓ 200 ok

     checks.........................: 100.00% ✓ 153779    ✗ 0     
     data_received..................: 121 MB  4.0 MB/s
     data_sent......................: 12 MB   410 kB/s
     http_req_blocked...............: avg=3.01µs  min=992ns    med=2.66µs   max=693.98µs p(90)=3.89µs  p(95)=4.87µs 
     http_req_connecting............: avg=15ns    min=0s       med=0s       max=308.55µs p(90)=0s      p(95)=0s     
     http_req_duration..............: avg=1.84ms  min=377.23µs med=934.47µs max=1.15s    p(90)=2.44ms  p(95)=6.02ms 
       { expected_response:true }...: avg=1.84ms  min=377.23µs med=934.47µs max=1.15s    p(90)=2.44ms  p(95)=6.02ms 
     http_req_failed................: 0.00%   ✓ 0         ✗ 153779
     http_req_receiving.............: avg=40.23µs min=12.31µs  med=34.68µs  max=4.91ms   p(90)=53.7µs  p(95)=68.91µs
     http_req_sending...............: avg=12.65µs min=4.27µs   med=11.03µs  max=5.88ms   p(90)=17.57µs p(95)=21.96µs
     http_req_tls_handshaking.......: avg=0s      min=0s       med=0s       max=0s       p(90)=0s      p(95)=0s     
     http_req_waiting...............: avg=1.78ms  min=348.98µs med=887.93µs max=1.15s    p(90)=2.36ms  p(95)=5.92ms 
     http_reqs......................: 153779  5125.8185/s
     iteration_duration.............: avg=1.93ms  min=446.6µs  med=1.02ms   max=1.15s    p(90)=2.57ms  p(95)=6.23ms 
     iterations.....................: 153779  5125.8185/s
     vus............................: 10      min=10      max=10  
     vus_max........................: 10      min=10      max=10  


running (0m30.0s), 00/10 VUs, 153779 complete and 0 interrupted iterations
default ✓ [======================================] 10 VUs  30s