[HN Gopher] Show HN: I finished v5 of a JVM framework I've spent...
       ___________________________________________________________________
        
       Show HN: I finished v5 of a JVM framework I've spent spent half a
       decade making
        
       Author : tipsee
       Score  : 274 points
       Date   : 2022-10-03 14:30 UTC (8 hours ago)
        
 (HTM) web link (javalin.io)
 (TXT) w3m dump (javalin.io)
        
       | sandGorgon wrote:
       | this is very cool. quick question though - do u have a gradle
       | build setup ? im new to java and saw this problem on spring boot.
       | That you needed to have this bunch of complex directory
       | structures cos of the way java packages worked. for e.g. the test
       | directories were parallel to the src directory, so they could be
       | named with the same package name.
       | 
       | for a single file...i can just run java. but it would be nice to
       | see a gradle setup that keeps simplicity and yet can have
       | thousands of files and testcases organised in a nice structure.
       | 
       | secondly, it is nice that you have Jetty hooks. Can you also have
       | CORS & proxy protocol ? its literally mandatory to have this
       | stuff if ur deploying on any of the k8s based clouds.
       | 
       | e.g. https://stackoverflow.com/questions/73225314/accept-proxy-
       | pr...
        
         | tipsee wrote:
         | I'm not super sure what you're asking, but Javalin doesn't care
         | at all about your directory structure. You can add it as a
         | dependency to any existing gradle project you have, and import
         | it like any other Java library (like java.lang.String).
        
         | matsemann wrote:
         | That's not a spring thing, but a java tools convention (having
         | a src and test folder etc). Nothing stops you from doing it
         | differently, but most tools work out of the box if you follow
         | that setup. So better to just do it than having to fight with /
         | configure every part of your pipeline.
        
       | kitd wrote:
       | Congrats on v5.
       | 
       | Have you tried it yet with GraalVM and native compilation?
       | 
       | Any gotchas?
        
         | tipsee wrote:
         | Thanks! We had some interest in running Javalin on GraalVM in
         | the past, but no one has updated the tutorial in many years. It
         | used to work though, so I bet it still would, if you really
         | wanted it to.
        
       | pron wrote:
       | Very nice!
       | 
       | Just a minor nitpick (for those who care about the details of
       | OpenJDK's development): virtual threads are not Project Loom, but
       | rather one of the JEPs contributed to the JDK by Project Loom.
       | There are two in JDK 19 (425 and 428), another in advanced stages
       | (429), and there will probably be more. OpenJDK Projects aren't
       | features but teams working on producing features focused on some
       | area and then offering them to the JDK.
        
         | tipsee wrote:
         | > Just a minor nitpick (for those who care about the details of
         | OpenJDK's development): virtual threads are not Project Loom,
         | but rather one of the JEPs contributed to the JDK by Project
         | Loom.
         | 
         | Thanks for clearing that up. Would adding a "from" be
         | sufficient?
         | 
         |  _and it uses Virtual Threads ("Project Loom") by default_
         | 
         |  _and it uses Virtual Threads (from "Project Loom") by default_
        
           | pron wrote:
           | Yeah, _from Project Loom_ (no need for quotes) would be
           | better, but even the current usage has become colloquial and
           | is okay. :)
        
             | tipsee wrote:
             | Fixed, thank you :)
        
       | helfire wrote:
       | How does the dev tooling work? Rebuild & restart the app each
       | time? I find working on any sizable codebase this can take
       | minutes even on the latest spring-boot. Quakrus has an
       | interesting live reloading classloader.
        
         | ris58h wrote:
         | If you use IDEA you can right-click modified .java file and
         | click 'Compile and Reload File'
         | https://www.jetbrains.com/help/idea/altering-the-program-s-e...
        
         | tipsee wrote:
         | Rebuild and restart. Javalin itself starts in milliseconds (the
         | test suite starts and stops servers across 600+ tests in less
         | than 10 seconds). If you run in debug mode in IDEA, or use some
         | hot-swapping tool like dcevm or jrebel, you won't always need
         | to restart. I don't think there will ever be a dedicated tool
         | provided by Javalin for this.
        
       | potency wrote:
       | Curious as to what has kept you motivated to continue working on
       | the project this long? So many open source developers don't last
       | nearly as long or jump to something new once the novelty of the
       | project wears off.
        
         | tipsee wrote:
         | I've been dogfooding it hard, which is a great incentive to
         | keep working on it. I think we have 20 Javalin projects where I
         | work. It's also gotten pretty popular lately (3m downloads last
         | 12months), which of course helps a lot :)
        
       | davidoniumz wrote:
       | I successfully used Javalin in a project using Kotlin + Koin for
       | dependency injection + jOOQ for database access. Was a joy to
       | setup and work in that project.
       | 
       | Thank you!
       | 
       | Congratulations on the major release and keep up the good work.
        
         | tdudzik wrote:
         | JDBI also could be really nice as a minimalistic layer for a db
         | access
        
       | didip wrote:
       | Javalin is the bomb! I don't know why Java community likes to
       | make things complicated.
        
         | takoid wrote:
         | "An idiot admires complexity, a genius admires simplicity, a
         | physicist tries to make it simple, for an idiot anything the
         | more complicated it is the more he will admire it, if you make
         | something so clusterfucked he can't understand it he's gonna
         | think you're a god cause you made it so complicated nobody can
         | understand it. That's how they write journals in Academics,
         | they try to make it so complicated people think you're a
         | genius." - Terry A. Davis
        
           | robertlagrant wrote:
           | Would prefer if this were worded more simply.
        
             | the_only_law wrote:
             | I mean, you see who it's attributed to...
        
         | manishsharan wrote:
         | I like Jetty. Javalin is nice for Kotlin but Jetty + java has
         | worked well for me.
        
           | Scarbutt wrote:
           | What do you use for routing and DI? do you use Jetty handlers
           | or the servlet API?
        
             | mateuszf wrote:
             | Dropwizard is cool if you write REST microservices. It uses
             | embedded jetty, JAX-RS, Jackson, metrics, etc.
             | 
             | As far as I know it's inspiration for Spring Boot, and it's
             | simpler and ready to use on production.
        
       | stevoski wrote:
       | This is Javalin and it is great. We switched to it a few months
       | ago from another micro-framework.
        
         | tipsee wrote:
         | Indeed it is! May I asked what you switched from?
        
       | iammiles wrote:
       | I just wanted to say thank you for your work. The straightforward
       | docs are some the best in my opinion when you want to go from
       | "How do I do ..." to answer.
       | 
       | I ended up using Javalin with Kotlin and SQLite to build my
       | wedding website.
       | 
       | Most of my projects are lucky to see the light of day, but with a
       | very persistent project manager and a simple lightweight
       | framework, I was able to ship a fantastic product with very
       | little fuss.
        
         | tipsee wrote:
         | Hey, thank you for using it. Single-page docs are also my
         | favorite, and Javalin/jdbi/SQLite is my goto for quick stuff!
         | 
         | > but with a very persistent project manager
         | 
         | Your partner? :D
        
           | Scarbutt wrote:
           | I can see how DI will be overkill for a wedding website and
           | Javalin/jdbi/sqlite is more than enough but for most business
           | applications written in Java you really wish you had started
           | with DI. Any DI libs you recommend for working with Javalin?
        
             | tipsee wrote:
             | Hard disagree on needing a DI library, manual DI is great.
        
               | Scarbutt wrote:
               | Disagree on using a lib? cause I guess doing manual DI is
               | still DI.
        
               | tipsee wrote:
               | Yes, disagree on needing a library. The way your comment
               | was worded made it seem to me like you were saying all
               | serious Java applications need a DI library, I'm sorry if
               | I misunderstood you. I prefer doing my ID manually, so no
               | recommendation :)
        
               | mkingston wrote:
               | Could you be more explicit, perhaps with an example? Do
               | you simply mean you prefer function/constructor
               | parameters over DI?
        
             | vips7L wrote:
             | Any DI lib would probably work, it depends on your
             | preferences and use cases though.
             | 
             | I'm personally a fan of Weld since its the reference
             | implementation of the CDI spec.
             | 
             | https://weld.cdi-spec.org/
             | 
             | A friend of mine built an MVC library around Javalin that
             | uses Dagger as the DI container:
             | https://github.com/jehugaleahsa/javalin-mvc
        
           | iammiles wrote:
           | Yep! At least they didn't mind when I was drinking on the
           | job.
        
         | peanut_worm wrote:
         | just wondering, what did you use SQLite for on a wedding
         | website?
        
           | yobert wrote:
           | I used PostgreSQL for my wedding website. People could RSVP,
           | say how many were coming, volunteer for support roles since
           | we did too much of it ourselves, etc.
           | 
           | It was overkill and I loved it.
        
           | samatman wrote:
           | For a website, the question should be why _not_ use SQLite.
           | 
           | Given the various compelling and (by now, here, I hope) well-
           | understood advantages, it should be the default choice.
           | Certainly for a site expecting hits in the mid-hundreds,
           | total. _Maybe_ ten simultaneous connections the day of?
        
             | NikolaNovak wrote:
             | Interesting, I interpreted the question completely
             | differently, i.e. why use database at all?
             | 
             | FWIW, I'm not in the web app world, so my wedding website
             | was a single page HTML; not a single page app, let alone a
             | content management system - I googled something like
             | "Wedding page HTML template", then grabbed a HTML template
             | from w3schools, opened it in notepad, and put my own words
             | and IMG tags. It looked pretty, was "responsive" by
             | default, took very little time to create, and worked
             | solidly.
             | 
             | I'm sufficiently old school / ignorant / pragmatic / lazy /
             | focused / _something_ , to wonder why complicate a wedding
             | page with anything else :-)
             | 
             | (I mean, I'm old and ignorant and simple enough that I keep
             | misinterpreting what "static site generator" is :P )
        
               | peanut_worm wrote:
               | Yeah that was what I meant but everyone else seems to be
               | commenting except the person I was replying to lol. I am
               | not attacking databases I am just wondering what they
               | used it for on a wedding website.
        
               | Scarbutt wrote:
               | _Interesting, I interpreted the question completely
               | differently, i.e. why use database at all?_
               | 
               | Maybe the wedding page has forms, needs to store data and
               | author is most familiar with Java or maybe they are
               | getting creative and are calling third party services for
               | convenience, lots of reasons. A simpler solution could be
               | nginx/cgi and a local file for the DB, or cloudfare
               | workers(you can render HTML from them) and their
               | key/value storage.
        
           | javajosh wrote:
           | It's been SOP for some time (at least 20 years) to use an
           | RDBMS to store your site's content and write a stateless
           | application server to pull data from it and compose a
           | response. Call it the "CMS pattern".
           | 
           | Static site generation, and a few other ideas, challenges
           | this basic pattern, but most of the worlds applications use
           | it. Javelin is trying to make the pattern better on several
           | axes, simplicity first-and-foremost, and not replace it.
        
             | freedomben wrote:
             | I truly mean this with love, but this is the most Java
             | comment I've seen in a long time :-D
             | 
             | And (in the Java/enterprise world) is completely correct.
        
               | javajosh wrote:
               | Funny, I had a LAMP stack in mind while writing it, and
               | more specifically WordPress. For all the enterprise Java
               | webapps out there, I bet there are 1000x more php sites.
               | And they all use the same basic cms pattern.
        
       | zmmmmm wrote:
       | Well done! Can't wait to see Loom become the default for web
       | frameworks.
       | 
       | Also spotted the Vue plugin - great to see this as so many light
       | weight web apps with a few pages can benefit from using Vue but
       | setting up all the build chain is such a drama that it's usually
       | not worth it. Look forward to trying it out.
        
         | tipsee wrote:
         | Thank you! The Vue support is the thing in Javalin I'm the most
         | proud of. There are a hundred web frameworks for the JVM, but
         | none of them have anything close to the Vue support Javalin
         | has. Some people think it's trash, but for me it's perfect.
        
       | rrampage wrote:
       | How does Javalin compare with Dropwizard which is also quite
       | lightweight?
        
         | tipsee wrote:
         | Javalin offers way less, it's more or less just the web routing
         | layer. No databases, no ORM, no config loading, etc.
        
       | danaugrs wrote:
       | Javalin is a great name!
        
       | ekvintroj wrote:
       | I usted Javalin a few months ago for a kotlin api. It's awesome!
        
       | recursivedoubts wrote:
       | Javalin is amazing.
       | 
       | Kudos.
        
       | kcbanner wrote:
       | Javalin has been powering one of my projects for years now
       | without issues. Really great framework. Thanks!
        
       | sgt wrote:
       | Great work. It's fascinating to see how "modern" Java looks these
       | days.
        
       | markhahn wrote:
       | doesn't JVM sniff of the 00's?
        
       | heurisko wrote:
       | Given Project Loom hasn't been available, how does it utilise
       | Virtual Threads already?
        
         | tipsee wrote:
         | If you run this on JDK19 with *--enable-preview*, Javalin will
         | use Virtual Threads for the Server ThreadPool (as well as all
         | other ThreadPools it has).
        
           | daveidol wrote:
           | How does it compare to coroutines in Kotlin?
        
             | tipsee wrote:
             | I mean, it sort of doesn't? Coroutines is a whole concept,
             | Virtual Threads can in most cases just replace
             | java.lang.Threads, which is how it's implemented in
             | Javalin. We just swap out the OS Threads for Virtual
             | Threads.
        
             | stefs wrote:
             | i'd be interested in this too. my guess: virtual threads
             | are slightly more memory efficient and slightly faster, but
             | same ballpark.
        
         | oweiler wrote:
         | Project Loom is in preview, and far from available. As far as I
         | can see, Javalin doesn't make use of virtual threads yet.
        
           | pron wrote:
           | Virtual threads are already available in the current version
           | of the JDK (19) as a Preview feature. Because it's not a
           | preview language feature but a preview API, libraries can use
           | it without compiling with --enable-preview, either with
           | reflection or by having the application supply a virtual
           | thread ThreadFactory, which means they can make use of
           | virtual threads if the application turns preview features on.
           | 
           | Preview _language_ features are different as they require
           | compiling with --enable-preview, which creates a  "poisoned"
           | class file that cannot be loaded at all without preview
           | enabled, so preview language features are not recommended for
           | use by libraries, but preview APIs are fine (see JEP 12:
           | Preview Features https://openjdk.org/jeps/12).
        
           | tipsee wrote:
           | It does :)
           | 
           | We use reflection to build the Virtual Thread Factory if the
           | user has Loom enabled in their enviroment: https://github.com
           | /javalin/javalin/blob/master/javalin/src/m...
        
       | speedgoose wrote:
       | It looks inspired by express.js, is it the case or are they both
       | inspired by an older framework?
        
         | samtheprogram wrote:
         | Express is inspired by Connect JS in terms of middleware --
         | middleware written for Connect works in Express. The middleware
         | style I believe is originally inspired by Rack, a Ruby project.
         | 
         | Sinatra, also Ruby, predates Express and is based on Rack (in a
         | similar way to Express, which used to be based on Connect if
         | I'm not mistaken).
         | 
         | I'm not sure what inspired Sinatra, but that's probably the
         | influence you're seeing in these frameworks.
        
         | tipsee wrote:
         | Both inspired by Sinatra, the OG :)
        
       | adamredwoods wrote:
       | I just started using this! Spring Boot seemed so convoluted,
       | having to go to a website to even begin. And then to have the
       | Tomcat dependency seemed like a heavy lift just to get a "hello
       | world" working. Virtual threads seems to be the way to go.
       | 
       | Virtual threads in Java 19: https://www.infoq.com/articles/java-
       | virtual-threads/
        
         | dopidopHN wrote:
         | Excellent resource on virtual thread by one of the authors!
         | Thanks.
         | 
         | I have to see I'm pleased to see Java moving fast those days.
         | 
         | I'm still digesting 17 and 18, but that give me a reason to
         | look at 19.
         | 
         | I honestly project loom was far from reaching that level of
         | "standardness" ... so I haven't looked into it in years
        
       | the-alchemist wrote:
       | Some quick questions: - are you using an already-existing HTTP
       | engine, like Jetty or Tomcat?
       | 
       | - how do virtual threads fit into a web framework?
       | 
       | - do virtual threads make debugging more difficult? (A more
       | general JVM question, I suppose)
       | 
       | - any performance / readability benefit, or just a coolness
       | factor?
        
         | tipsee wrote:
         | _are you using an already-existing HTTP engine, like Jetty or
         | Tomcat?_
         | 
         | Yes, Javalin is built on top of Jetty.
         | 
         |  _- how do virtual threads fit into a web framework?_
         | 
         | Most JVM web frameworks (Jetty included) have a thread based
         | request lifecyle (one thread handles one request from beginning
         | to end). The java.lang.Threads are extremely expensive (~1mb
         | memory), while Virtual Threads are very cheap (~0mb memory). We
         | also have another ThreadPool for JSON streaming, and one for
         | writing async responses. Using Virtual Threads for these things
         | reduces overall memory pressure.
         | 
         |  _- do virtual threads make debugging more difficult? (A more
         | general JVM question, I suppose)_
         | 
         | Not that I know, but I've never used this in production myself.
         | 
         |  _- any performance / readability benefit, or just a coolness
         | factor?_
         | 
         | The alternative here is java.lang.Threads, so primarily the
         | memory footprint. There is no readability difference. When
         | developing, you don't see this at all.
        
       | NightMKoder wrote:
       | I haven't tried this framework, but just looking at some
       | examples, the web sockets and sse seem a bit out of place. In a
       | Loom world you'd expect these to use channels or queues or
       | something similar in a loop - not callbacks. Callback hell is
       | what virtual threads try to avoid. I'm not sure if loom has any
       | primitives like go's multi-channel select that might make this
       | workable though.
       | 
       | In either case Loom and frameworks that use it are super
       | exciting! I'm looking forward to removing the 20 different thread
       | pools we need to avoid deadlocks and just using the common one in
       | our Clojure apps.
        
         | uup wrote:
         | Having recently implemented a WebSocket service in Go, the
         | Javalin way seems preferable. This is what a similar Go version
         | would look like:                   wsHandler := func(w
         | http.ResponseWriter, r \*http.Request) {             conn, err
         | := upgrader.Upgrade(w, r)             if err != nil {
         | w.SendStatus(http.StatusInternalServerError)
         | return             }                  ctx, ctxCancel :=
         | context.WithCancel(context.Background())             var wg
         | sync.WaitGroup                  wg.Add(1)             go func()
         | {                 defer sync.Done()                      for {
         | msg, err := conn.ReadMessage()                     if err !=
         | nil {                         return                     }
         | }             }()                  msgPipe := make(chan []byte,
         | 1024)             wg.Add(1)             go func() {
         | defer wg.Done()                 for {
         | select {                     case <-ctx.Done():
         | return                     case msg := <- msgPipe
         | if err := conn.WriteMessage(msg); err != nil { return }
         | }                 }             }()                  go func()
         | {                 <- ctx.Done()                 wg.Wait()
         | close(msgPipe)             }()         }
         | 
         | I like Go, but I found writing WebSocket code very annoying.
        
         | pron wrote:
         | We don't have selectable channels yet, but they're not needed
         | as much in Java as they are in Go, because often multiple
         | channels are used to signal cancellation, whereas in Java
         | there's a standard mechanism for cancellation
         | (Thread.interrupt() at the low level, with Future.cancel being
         | higher level, and JEP 428's structured concurrency being higher
         | level still https://openjdk.org/jeps/428).
        
       | simonw wrote:
       | I find that hello world example very pleasant to look at. Love
       | that it's effectively a one-liner.                   public
       | static void main(String[] args) {             var app =
       | Javalin.create(/*config*/)                 .get("/", ctx ->
       | ctx.result("Hello World"))                 .start(7070);
       | }
        
         | jannes wrote:
         | Looks very similar to Express.js which came out in 2011 and has
         | been one of the most popular frameworks in the Node.js world.
         | 
         | https://expressjs.com/en/starter/hello-world.html
        
       | dang wrote:
       | Related:
       | 
       |  _Show HN: Javalin 1.0 - A Kotlin /Java web framework_ -
       | https://news.ycombinator.com/item?id=15644430 - Nov 2017 (87
       | comments)
       | 
       |  _Show HN: Javalin, a Java /Kotlin REST API Framework_ -
       | https://news.ycombinator.com/item?id=14434089 - May 2017 (21
       | comments)
        
         | tipsee wrote:
         | The good old days!
        
       | pkulak wrote:
       | I'm pretty sure the "Hello Javalin World" Kotlin example won't
       | compile, just FYI.
        
         | tipsee wrote:
         | Seems to compile fine here, what's the issue?
         | 
         | Edit: I was looking at the wrong snippet, the offending snippet
         | has been fixed.
        
           | pkulak wrote:
           | Huh, I wonder what's different with my setup. I would need to
           | put curly braces around that closure before it would compile,
           | i.e:                   .get("/", { ctx -> ctx.result("Hello
           | World") })
           | 
           | Closures defined only by the arrow are a Java thing... or so
           | I thought. :D
        
             | tipsee wrote:
             | > Closures defined only by the arrow are a Java thing... or
             | so I thought. :D
             | 
             | In fairness, I think you did copy the Java version. There's
             | a little switch in the code boxes where you can toggle the
             | language, if you switch to Kotlin you get the version with
             | trailing closures :)
             | 
             | Edit: I'm an idiot, I see the snippet you mean now. It's
             | been updated now, give it a minute.
        
               | pkulak wrote:
               | Sweet, thanks!
        
           | gavinray wrote:
           | Probably not used to seeing lambdas inside of parens:
           | .get("/", ctx -> ctx.result("Hello World"))
           | 
           | Could also be written as                 .get("/") { ctx ->
           | ctx.result("Hello World") }
           | 
           | The second form seems much more common in Kotlin.
        
             | tipsee wrote:
             | Yeah, no, he was 100% correct, I was just looking at the
             | wrong snippet. It's been fixed now :)
        
       | de6u99er wrote:
       | Peeking int the docs, it reminds me a little bit of Vert-X. What
       | do you think qbout such a statement?
        
         | tipsee wrote:
         | I respect Vert.x a lot, so I'm flattered, but Vert.x is a huge
         | beast with focus on performance. Javalin is basically a tiny UX
         | layer on top of Jetty. I don't think they are very similar
         | frameworks. Javalin's focus is on being "good enough" all
         | around, but with the best possible developer experience.
        
       | jpgvm wrote:
       | I have used Javalin for a number of Kotlin backend projects of
       | late, thanks for all your hard work!
        
       | stefs wrote:
       | i'm using javalin in production without problems. i have a custom
       | html templating engine and can't wait to try the virtual threads.
       | 
       | had no problems at all. i really like it. thanks!
        
       | moralestapia wrote:
       | Congratulations! This is great!
       | 
       | Java deserves its comeback among the wave of nu-programming we
       | are going through.
        
         | tasuki wrote:
         | > Java deserves its comeback among the wave of nu-programming
         | we are going through.
         | 
         | What is nu-programming? And why would Java deserve a comeback?
        
           | moralestapia wrote:
           | >nu-programming
           | 
           | I made that one up.
           | 
           | >And why would Java deserve a comeback?
           | 
           | Java is an extremely mature piece of technology, and having
           | used it on the enterprise, I can attest that few things come
           | close on flexibility and stability. Also, functional
           | languages on top of the JVM (clojure, kotlin, scala) are very
           | interesting on their own. Java deserves some love from this
           | new wave of paradigm changes like "write-once-run-anywhere"
           | v2.0, monadic programming, serverless functions, etc...
        
         | stefs wrote:
         | you can also use it with kotlin
        
       | voidfunc wrote:
       | Javalin is great and a worthy successor to its predecessor
       | Sparkjava
        
         | vincnetas wrote:
         | What happened to sparkjava?
         | 
         | Edit: looks like its alive and kicking :
         | https://sparkjava.com/news
        
       | cies wrote:
       | Congrats on the release! I reviewed Javalin lately and it was
       | high on my list. We use quite a bit of Kotlin and look for a
       | framework. I really dislike the magic that annotations bring to
       | most popular Java frameworks (and Hibernate). I prefer most is
       | just code". Kotlin helped us a lot in making our code more type
       | safe, especially the KProperty way of referring to methods made a
       | difference.
       | 
       | Though I ended up leaning towards KTor, with Javalin as a close
       | second.
       | 
       | How would anyone with more knowledge compare the two (Javalin and
       | KTor)?
        
       | spapas82 wrote:
       | Can we use this to render traditional apps (no js frameworks)?
        
         | skibz wrote:
         | Absolutely!
        
           | spapas82 wrote:
           | Excellent thank you! Which template engines are supported?
        
             | kcbanner wrote:
             | https://javalin.io/documentation#views-and-templates
        
       | freedomben wrote:
       | This looks great! I did Java professionally for years but when
       | all the jobs moved to EE I bailed for Ruby/Rails and similar.
       | Java the language I've always really enjoyed. It's the frameworks
       | and hundreds of design patterns that repelled me. I felt like
       | they were all needlessly complex. If frameworks like this one
       | were more common in Java world, I may never have left.
       | 
       | This looks really nice! I wish more Java devs approached things
       | with KISS and simple in mind, rather than looking at every
       | problem as a way to apply some obscure design pattern that
       | involves 15 levels of abstraction and indirection for a
       | relatively simple microservice.
        
       ___________________________________________________________________
       (page generated 2022-10-03 23:00 UTC)