[HN Gopher] Javalin - a simple web framework for Java and Kotlin
       ___________________________________________________________________
        
       Javalin - a simple web framework for Java and Kotlin
        
       Author : saikatsg
       Score  : 133 points
       Date   : 2024-02-11 12:55 UTC (10 hours ago)
        
 (HTM) web link (javalin.io)
 (TXT) w3m dump (javalin.io)
        
       | dkpk wrote:
       | I read about the Spark framework on another thread. Looks very
       | similar. https://news.ycombinator.com/item?id=39331126
        
         | yCombLinks wrote:
         | It's basically a fork and spark dev was abandoned
        
       | TeaVMFan wrote:
       | This looks useful for server-side web apps. For using Java/Kotlin
       | in a single-page app, I've been using Flavour successfully for
       | many years.
       | 
       | I've written a book about it here:
       | https://frequal.com/Flavour/book.html
        
       | dj_gitmo wrote:
       | What are the drawbacks of these "simple" frameworks? Do you run
       | the risk of being constrained if your requirements expand?
        
         | michaelcampbell wrote:
         | Sure? I mean any framework will constrain you to what it
         | provides. These frameworks usually include some set of
         | functionalities:
         | 
         | - an underlying service to listen for http/https requests (eg:
         | "web server")
         | 
         | - easily map inputs to code/services ("routing"); often also
         | providing helper functionality to extract data from paths, map
         | and convert JSON (etc) to domain objects
         | 
         | - some way to inject your data into a return "view" (json,
         | html, xml, ???). Might also include reusable view code snippets
         | (eg: "partials"), and/or some "design pattern" (eg: "layouts")
         | system
         | 
         | - an ORM or other db-layer abstraction
         | 
         | - some background job processing abstraction
         | 
         | That's about all you need; the extent to which the framework
         | simplifies doing those things is akin to the amount of
         | constraints. Everything else is gravy.
         | 
         | Do note that "big" frameworks that provide ALL of that plus
         | more can often be harder to work with since you might be forced
         | to learn more than you need, and it's overwhelming.
         | 
         | There's also the concern of modularity... if I don't like their
         | ORM, can I use my own? How hard is it to add functionality not
         | provided, etc.
        
           | andrewoneone wrote:
           | Totally agree. The modularity and the amount of "batteries
           | included" can eventually become a negative. The last thing I
           | want is for someone to reinvent RxJava yet it seems to happen
           | in every one of the more bloated frameworks. "Are you
           | familiar with reactive programming? Oh cool - but are you
           | familiar with mixing RxJava and Spring's reactor? That's what
           | we now have and it's a real treat sometimes." This is just
           | one sad and possibly poorly outdated example as I haven't
           | worked with spring in some years now.
        
             | michaelcampbell wrote:
             | I worked in a place using Django, with dozens of additional
             | plugins and enhancements.
             | 
             | And my PR's were routinely flagged for writing 3-5 lines of
             | idiomatic python that any python programmer (indeed, any
             | PROGRAMMER) would have understood instead of spending half
             | a day to try and find the "Django way" (or worse, the
             | "whatever 5000 line plugin we installed to save the
             | programmer from having to repeat 2 lines of idiomatic
             | python 10-12 times") way to do it.
             | 
             | Their (IMO insane) adherence to the common, but
             | misunderstood idea of DRY was insanely unproductive.
             | 
             | These frameworks become "languages" in themselves, and
             | unless you're in it all day every day, it's _harder_ to get
             | things done due to their incredibly large attack surface.
        
               | ahmedfromtunis wrote:
               | Can you give an example of this "Django way" code vs
               | pythonic code dichotomy?
               | 
               | I'm very curious to see how that may look like. I've been
               | using Django for years now and was never faced with such
               | choice.
        
           | fuzztester wrote:
           | >Sure? I mean any framework will constrain you to what it
           | provides.
           | 
           | By definition, almost, compared to the bunch of libraries
           | approach, whch is more flexible and composable.
        
         | StevePerkins wrote:
         | It's a philosophical thing.
         | 
         | The advantages of microframeworks (e.g. Sinatra, Flask,
         | Javelin, etc) are that as your needs expand, you can bolt-on
         | the additional functionality as you see fit, from a "best of
         | breed" selection of your favorite libraries.
         | 
         | The advantages of batteries-included frameworks (e.g. Rails,
         | Django, Spring, etc) are that your application is easier to
         | find people to work on, and has a greater change of remaining
         | coherent and maintainable for longer.
         | 
         | In the real world with microframeworks, some rock star starts a
         | greenfield project, and has a delightful fun time selecting
         | their personal picks of various community libraries to bolt
         | functionality on top of the microframework. Then that original
         | developer moves on 6 months later. The best-case scenario is
         | that half of their pet community libraries are no longer being
         | maintained 12 months after that, and the team has to constantly
         | sink time into migrating pieces of the app to other actively
         | maintained libraries. The worst-case scenerio is that you get
         | the next-generation rock star, who wastes time ripping out
         | pieces for no real reason other than using their own personal
         | pet favorites.
         | 
         | In my experience, the microframeworks are ideal for apps where
         | you can be fairly confident that the scope will never expand
         | (e.g. simple Lambda functions). Otherwise, they're popular toys
         | for startups, and nooks and crannies of large enterprises where
         | no one's really providing any oversight over the juniors.
        
           | the-smug-one wrote:
           | Is the main advantage of frameworks then a social thing? You
           | can depend on the future development of the framework as a
           | whole, as opposed to a bunch of smaller libraries, so it
           | doesn't matter if the sum total quality of those smaller
           | libraries is greater than the framework.
           | 
           | Does it also have the advantage of not having to remember to
           | import things? Like, does Spring prevent CSRF attacks etc.
           | out of the box, and it's very difficult to accidentally
           | create a vulnerability using it?
        
             | olavgg wrote:
             | Yes Spring Boot 2.2+ prevent csfr attacks out of the box.
        
             | mattgreenrocks wrote:
             | Big factor in rise of frameworks is outsourcing the
             | architecture to it.
             | 
             | Lots of devs need the prebaked structure. It is honestly
             | helpful in many cases, but can also be a frustrating maze
             | at times to find the hook/extension point you need.
        
             | okeuro49 wrote:
             | Spring Boot uses a lot of libraries and integrates them for
             | you to make sure they all work together.
        
       | jmspring wrote:
       | I used Javalin for a startup I helped with a few years back. I
       | found It much easier and lightweight to turn up REST endpoints
       | compared to Springboot/etc.
       | 
       | While it may not be as featureful as Springboot, it could
       | generate swagger specs and had the features I needed at the time.
        
         | cryptos wrote:
         | In my experience the web layer is (or should be) pretty thin,
         | so a framework in this layer shouldn't change too much in the
         | overall application architecture.
        
       | _bax wrote:
       | Java _is_ agile, like said by @venkat_s
        
       | michaelcampbell wrote:
       | I'm a little surprised this framework hasn't gotten more
       | mindshare. I've found it pretty easy to grok and work with.
       | 
       | Seems right now everyone is under Spring's "boot", if you'll
       | pardon the pun.
        
         | BossingAround wrote:
         | It's either Spring, or Java EE's way (together with the new
         | Jakarta EE paradigm, which is actually pretty cool if you ask
         | me). I've seen the latter a lot more in the enterprise sphere.
        
           | zokier wrote:
           | Jakarta EE was purely a rebrand of Java EE, what do you mean
           | new paradigm?
        
             | ysleepy wrote:
             | https://microprofile.io/
        
               | fuzztester wrote:
               | >MicroProfile
               | 
               | >Optimizing Enterprise Java for a Microservices
               | Architecture
               | 
               | Captain Kirk:
               | 
               | When the spaceship nears colossal planet Enterprise, two
               | kinds of developers on board will be revealed:
               | 
               | - those who jetpack enthusiastically down to the planet
               | (their Buzzwordite (TM) foam resumes will softpad their
               | landing)
               | 
               | - and those who retrorocket desperately away, seeking
               | lean, mean, computing machines
               | 
               | Spock:
               | 
               | Logical flaw - you forgot off-by-one errors.
        
               | zokier wrote:
               | [delayed]
        
           | arunix wrote:
           | What is cool about the new Jakarta EE paradigm?
        
         | adamredwoods wrote:
         | Years ago when I was investigating Spring and Java EE, I was
         | taken aback by how much additional work was involved. Not only
         | do some tutorials only show how to install through Java's
         | dedicated IDE, but also deciding on which application server to
         | use, which adds another layer of technical decisions and slows
         | down the process of "quickly testing" frameworks.
         | 
         | Javelin breaks free of that. Excellent stuff!
        
           | reactordev wrote:
           | @SpringBootApplication was all you needed on top of a main
           | class. The biggest issue is somewhere along the Spring ->
           | Pivotal -> VMWare -> Spring hot potato, their tutorials and
           | documentation fell off a cliff. Everything became "just use
           | initializer..."
        
           | StevePerkins wrote:
           | If you were "deciding which application server to use", then
           | that WAS "years ago" indeed! The paradigm shifted, from
           | applications being deployed to a server such as Weblogic or
           | Websphere, to applications bundling their own HTTP server
           | like Node or Golang. This shift happened around 15 years ago.
           | Modern Java development looks almost nothing like it did back
           | in that era.
        
             | bbkane wrote:
             | Do you have any good Modern Java web dev links you could
             | drop?
        
         | reactordev wrote:
         | Micronaut has a share of the space too.
         | 
         | https://micronaut.io/
         | 
         | However, you're right that Spring Boot has the lions share of
         | the Java ecosystem.
        
       | sureglymop wrote:
       | What about Ktor? I always see that being pushed, maybe because
       | it's from Jetbrains..
        
         | michaelcampbell wrote:
         | What about it? This is just a post about Javalin.
         | 
         | I often wonder why people always post these "sure, but what
         | about..." replies. Hot take: There's more than one way to skin
         | a cat, here's one.
        
           | ydnaclementine wrote:
           | They're looking for comparisons dawg
        
         | jeltz wrote:
         | Not a fan of it. Too much DSL magic for unclear gains, at least
         | in the way the manual recommends you to write your code.
        
       | cushpush wrote:
       | "simple"
        
       | binkHN wrote:
       | I glanced at this a while back, but, ultimately, went with Ktor.
       | Reason being, well, I was using Kotlin and wanted something even
       | more simple.
        
       | sureglymop wrote:
       | I don't like that the logging just happens implicitly? Like, it
       | asks to install slf4j... But can't I just start out with the
       | standard kotlin logger before installing another dependency. That
       | part imo is a little underdocumented.
        
         | michaelcampbell wrote:
         | https://javalin.io/tutorials/javalin-logging seems pretty good,
         | IMO; YMMV of course.
         | 
         | Logging in Java has always been a weird amalgam of interface
         | libraries and implementation libraries with an XKCD'ish "14
         | competing standards" issue.
        
           | kaba0 wrote:
           | Either slf4j or java's standard lib API interface (since java
           | 9 I believe) works with everything basically.
        
       | KronisLV wrote:
       | Personally, I rather enjoyed Dropwizard, because it had a bunch
       | of idiomatic Java packages that most developers would have
       | already seen elsewhere, all put together in a way that doesn't
       | seem to have too much boilerplate:
       | 
       | https://www.dropwizard.io/en/stable/
       | 
       | https://github.com/dropwizard/dropwizard
        
         | waynesonfire wrote:
         | I'm a fan of dropwizard but couldn't get swagger to work with
         | it. Maybe it's improved since then?
        
       | fuddle wrote:
       | Kudos for the great documentation.
        
       | BossingAround wrote:
       | Wow, this is a blast from the past for me - I was examining the
       | framework in 2015. Amazing to see it's still well and alive. Back
       | then, I'd simply use some resteasy framework.
        
       | simonw wrote:
       | This is a really nice API design:
       | https://javalin.io/documentation
       | 
       | Feels lightweight but powerful - it seems to cover everything I
       | need from a framework in terms of URL routing and
       | request/response handling, with minimal cruft and boilerplate.
        
         | jmspring wrote:
         | That was why I picked it awhile back. I hate that most Java
         | development these days has a large component that deals with
         | writing XML. It allowed me to focus on the code I needed to
         | write and not figure out what parts I needed to cobble
         | together.
        
           | matsemann wrote:
           | Are you comparing to legacy java applications? Haven't
           | written xml in soon a decade in spring boot.
        
         | kitd wrote:
         | One of the good things about it is that using asynchrony is
         | optional. If you don't have to call out anywhere to build the
         | response, processing can all stay in the handler's calling
         | thread. If you do, you can return a future and have the library
         | handle the async for you.
         | 
         | One downside is that it is based on Jetty which isn't
         | considered the most performant backend. A lib with a similar
         | API but based on Netty is Jooby [1] which scores well in the
         | Techempower benchmarks.
         | 
         | [1] - https://jooby.io/
        
           | javajosh wrote:
           | _> Jetty which isn't considered the most performant backend_
           | 
           | This definitely needs some supporting links. Jetty itself is
           | extremely fast in my experience.
        
         | silvestrov wrote:
         | The cookie support seems lackcluster. I'd prefer good support
         | for real cookies instead of "stuff JSON into a single cookie".
         | 
         | Also the URL parameter API is clumbersome:
         | Integer myValue = ctx.queryParamAsClass("value",
         | Integer.class).getOrDefault(788) // validate value
         | 
         | I would prefer some specialized API like:                   int
         | myValue = ctx.queryParamAsInt("value", 788);
        
           | matsemann wrote:
           | Given that it's kotlin, one could easily make an extension
           | function like that yourself and enhance the API to your
           | liking.
        
       | derefr wrote:
       | My API SaaS company chose Javalin for our API backend to start
       | with, for several reasons:
       | 
       | * it is "just enough" web framework for our needs, without all
       | the bloat that a framework targeting browsers/serving HTML would
       | have;
       | 
       | * it has an annotation-based OpenAPI auto-summarization plugin,
       | to allow us to immediately get some docs and autogenerated SDKs
       | up;
       | 
       | * and it explicitly owns the lifecycle for its components --
       | using e.g. an embedded Jetty instance that gets started +
       | configured _in code_ by the framework -- where you can inject
       | config into that code, or replace it wholesale. (This is what we
       | were used to in other web frameworks, and is unusual in Java
       | land, where web servers seem to be separate  "background
       | services" that happen to start up independently in the same JVM,
       | and then auto-discover and runtime-bind to your web service's
       | "background service" through XML files the framework generates
       | and the web server probes for. Which is a bit much when you're
       | not running an enterprise-y "app server" with tons of different
       | servlets mounted to it that can be hot-upgraded without
       | restarting the server, but instead a single-purpose Java app in a
       | Docker container as a k8s Deployment.)
       | 
       | That being said, as our company grew, we eventually ran into the
       | disadvantages:
       | 
       | 1. Scanty documentation.
       | 
       | The https://javalin.io/documentation page is all you get. Want,
       | say, a list of the HTTPResponse exceptions Javalin offers? Or to
       | know the _types_ -- rather than just the _behaviors_ -- of the
       | getters and setters on Context? Well, too bad -- go read the
       | (Kotlin) source code!
       | 
       | (Why no per-module JavaDoc docs? Even the hollowed-out docs that
       | just give constants + methods, that you get by generating docs
       | from a module with no docstrings, would be better than _no_
       | JavaDoc! IDEs do give you some of the same info as a trivial
       | Javadoc, but JavaDoc docs are a lot more browsable as a reference
       | when you don 't know the _name_ of the thing you want, just the
       | _type_.)
       | 
       | 2. Static routes!
       | 
       | Javalin routes must be bound to _static methods_ of Java classes.
       | You can 't+ build an object, pass the object to your Javalin app
       | constructor, and have it bind routes to that object's methods.
       | Which makes constructing any kind of DDD service contexts -- and
       | having them be _testable_ , with separate e.g. DB providers in a
       | test context -- near-impossible. Javalin and _dynamic_ Dependency
       | Injection -- the kind you do in tests -- just don 't get along.
       | 
       | + Or, well, you _can_ do that -- in that you can bind each route
       | to a _closure_ which _calls_ the method on the object. But those
       | closures need to be able to bubble arbitrary checked exceptions
       | back to the Javalin exception handler (which the trivial examples
       | in the Javalin docs carefully avoid the need for by only calling
       | pure code.) Which means so you can 't use the syntax-sugar'ed
       | kind of functional closure. So each route balloons into 10 lines
       | of instance-subclass boilerplate, and your routes module is no
       | longer a readable + greppable DSL definition of "what your app
       | reacts to", but instead a big mess.
       | 
       | 3. No support for writing Java Servlet middleware.
       | 
       | Javalin _uses_ servlets under the covers, but doesn 't expose the
       | servlet "stack" for injection. Instead, you have to write Javalin
       | plugins (Which haven't been good for much for most of Javalin's
       | lifetime -- though they seem to be pretty flexible _now_ , so
       | this might not be as much of a concern if you're doing a
       | greenfield Javalin project today.)
       | 
       | I'm guessing that most devs still just end up just dumping all
       | their middleware-ish concerns (auth, rate-limiting, etc) in
       | app.before + app.after. Which thereby accidentally leaks
       | resources -- because some exceptions can cause app.after to not
       | run! (You have to do a little dance with app.after and
       | app.exception calling into common code -- essentially "rewriting
       | the framework to do the thing it should have done" -- to resolve
       | that.)
       | 
       | 4. The Javalin devs are slow to add very critical features that
       | tons of people ask for, sometimes leaving outstanding requests on
       | the backburner for years.
       | 
       | Until Javalin 6, there was no app.beforeMatched, and therefore,
       | no request-lifecycle callback point for "after routing has been
       | resolved, but before actually calling the route."
       | 
       | So, before recently, you couldn't do rate-limiting or auth or etc
       | _generically in middleware_ , while also taking the static route-
       | name of the resolved endpoint -- the string that looks like
       | "/account/:id/binding" that the Javalin context gives you access
       | to _inside_ your controller code -- into account as an input.
       | Instead, to do this, you had to let the route trigger, and then
       | call generic code from _inside_ the controller (see e.g.
       | https://javalin.io/plugins/how-to#creating-a-plugin-with-con...,
       | which seems to show that the Javalin devs still think of this as
       | the idiomatic way to do this.)
       | 
       | Even with this _particular_ feature request finally resolved,
       | there are still several outstanding ones. And given the shape of
       | Javalin as a framework, the way to work around these missing
       | features, always ends up involving writing redundant generic code
       | inside your MVC controllers. If you do this enough times -- and
       | you follow the natural desire to factor them out -- then you end
       | up basically building a framework on top of your framework! (And
       | then, when these new features _do_ finally come along, you 're
       | already added all this now-unneeded architecture that's very hard
       | to get rid of.)
       | 
       | ---
       | 
       | A while ago, we got fed up with the disadvantages -- so we're
       | very likely going to be moving to Spring Boot.
       | 
       | At some point. (Given the particular shape Javalin forces your
       | code into, though, such a move is a lot of work!)
        
         | breakpete wrote:
         | Regarding 2, you can actually bind routes to instance methods:
         | var obj = new SomeObjectWithHandlerMethods(dependency);
         | var app = Javalin.create().get("/",
         | obj::handlerMethod).start();
         | 
         | Edit: For 4, Javalin 6 also has some documentation regarding
         | Servlets here: https://javalin.io/documentation#adding-other-
         | servlets-and-f...
        
           | derefr wrote:
           | Strange -- I swear this wasn't the case. I and several other
           | devs tried for a good three weeks to get Javalin to accept
           | such route bindings. This _was_ a year or two ago, though.
           | Maybe the interface type for a handler function was changed
           | in some more recent version of Javalin?
        
             | breakpete wrote:
             | Not sure about the older versions of Javalin, but from my
             | experience with v5+ it just uses regular Single Abstract
             | Method conversion for the Handler interface, which has a
             | single method with just one parameter (the Context).
        
       | Yhippa wrote:
       | Just reading through the examples, the fluent API really shines.
        
       | vbezhenar wrote:
       | If you like lightweight libraries, check out Helidon SE 4. It's
       | built on Java 21 virtual threads, embraces blocking paradigm,
       | built by Oracle, fully open source, of course, comes with some
       | batteries included. Worth checking out, IMO.
        
         | kitd wrote:
         | Note that Javalin also supports virtual threads.
         | 
         | https://javalin.io/documentation#concurrency
        
           | vips7L wrote:
           | Supporting and being built upon them is a bit different.
           | Helidons web server was written from scratch with virtual
           | threads in mind.
        
       | pipeline_peak wrote:
       | Should've called it Kava
        
       | ysleepy wrote:
       | Nowadays I prefer starting with a microprofile subset consisting
       | of jersey+jetty offering the standard JAX-RS APIs.
       | 
       | Is really lightweight at only 6MiBs shaded and grows
       | opportunistically into the microprofile stack of quarkus etc. -
       | you can even integrate the jax-rs bits into spring if you want.
       | Microprofile has a bunch of standards compliant implementations,
       | so you aren't locked into a specific implementation project.
       | 
       | I think the option is overlooked because the landscape is complex
       | and this setup doesn't have a marketing name, but it is very
       | stable and polished.
       | 
       | You also get IDE support, because JAX-RS is part of microprofile,
       | and formerly part of JavaEE.
        
       | mightyham wrote:
       | Springboot's dependency injection, auto configuration and yaml
       | configuration system is a value proposition that I find hard to
       | beat. I find it's fairly effortless to build almost any kind of
       | backend software, and if I want something "lightweight" I
       | probably wouldn't use java in the first place.
       | 
       | While that's my pragmatic view, to be less critical, I am glad to
       | see a project that provides a robust and elegant API for building
       | rest services in Java.
        
         | nullzzz wrote:
         | The aforementioned are huge detractors for me to be honest. I
         | find a no-magic, code-only solution like Javalin (and Express
         | etc) far more intuitive.
        
         | koufatz wrote:
         | It's actually not that hard to beat. Quarkus proved that it's
         | way better than Spring Boot in a lot of aspects based on open
         | standards and battle tested frameworks like Vertx. Also on
         | Quarkus you can use in parallel blocking and non-blocking IO
         | and also high level declarative routes with annotations to
         | lower lever vertx routes and handlers.
        
           | vips7L wrote:
           | You don't even need a framework to beat it.
           | 
           | Pick a DI library: Guice, Avaje Inject, Weld, countless
           | others
           | 
           | Pick a configuration library: Avaje Config, Typesafe Config,
           | Microprofile Config, countless others.
        
             | xienze wrote:
             | There's a lot more to Spring Boot than DI and
             | configuration.
        
       | dang wrote:
       | Recent and related:
       | 
       |  _Spark - A web micro framework for Java and Kotlin_ -
       | https://news.ycombinator.com/item?id=39331126 - Feb 2024 (35
       | comments)
        
       ___________________________________________________________________
       (page generated 2024-02-11 23:01 UTC)