[HN Gopher] Show HN: Minum - A minimal Java web framework
___________________________________________________________________
Show HN: Minum - A minimal Java web framework
I am happy to announce my minimalist zero-dependency web framework,
Minum, is out of beta. http://github.com/byronka/minum You will
be hard-pressed to find another modern project as obsessively
minimalistic. Other frameworks will claim simplicity and minimalism
and then, casually, mention they are built on a multitude of
libraries. This follows self-imposed constraints, predicated on a
belief that smaller and lighter is long-term better. Caveat
emptor: This is a project by and for developers who know and like
programming (rather than, let us say, configuring). It is written
in Java, and presumes familiarity with the HTTP/HTML paradigm.
Driving paradigms of this project: * ease of use * maintainability
/ sustainability * simplicity * performance * good documentation *
good testing It requires Java 21, for its virtual threads (Project
Loom)
Author : 7ep
Score : 81 points
Date : 2023-09-25 18:07 UTC (4 hours ago)
(HTM) web link (github.com)
(TXT) w3m dump (github.com)
| rezaprima wrote:
| I didn't see looping support for templating, like for rendering
| collection to HTML table. Did I miss something?
| beders wrote:
| Names.
|
| The problem always comes down to naming.
|
| `StartLine.Verb.GET`
|
| is not a good name.
|
| Neither StartLine nor Verb are used in that context in the HTTP
| spec.
|
| The most widely used name for GET/POST etc. is Method.
|
| The author will find that these seemingly small things will
| hinder adoption.
| ivan_gammel wrote:
| Agree. Looking at the example project, this is not a single
| case, when a name could be better. Helpers and Utils are naming
| anti-patterns, so naming function \(de)serializeHelper\ is not
| a good idea.
| 7ep wrote:
| Names. One of the two hard problems in computer science,
| along with cache invalidation. And off-by-one errors.
| 7ep wrote:
| Valid point. I was going off documentation like here:
| https://developer.mozilla.org/en-US/docs/Web/HTTP/Messages#s...
| jen20 wrote:
| That page uses Method though, and places nouns at equal
| importance with verbs when describing them?
| [deleted]
| KronisLV wrote:
| The size statistics page is super cool:
| https://github.com/byronka/minum/blob/master/docs/size_compa...
|
| Reasoning this way about software and dependencies more often
| seems like a good thing, just so we're aware of what we're
| actually getting into, especially with projects that use npm.
|
| I actually hadn't heard of Javalin before, which also seems nice:
| https://javalin.io/
|
| Aside from that, I've also had good experiences with Dropwizard -
| which is way simpler than Spring Boot but at the same time uses a
| bunch of idiomatic packages (like Jetty, Jersey, Jackson, Logback
| and so on): https://www.dropwizard.io/en/stable/
|
| I do wonder whether Minum would ever end up on the TechEmpower
| benchmarks and how it'd stack up against the other
| libraries/frameworks there, those benchmarks are pretty
| interesting.
| mongol wrote:
| I can see clear value in a framework that minimizes dependencies.
| The choice to supply both a web framework and a persistence /
| database layer puzzles me somewhat. I understand this can be the
| basis of an "everything included" framework, but I think
| especially for persistence, most would like to make a conscious
| choice independently.
| 7ep wrote:
| There's nothing to prevent using any external db if desired. In
| fact i'm doing that for a client.
| mongol wrote:
| Sure, but do you want to elaborate why you included it?
| 7ep wrote:
| in case you truly want to go as absolutely minimal as
| possible. i do. for my own personal projects, i use that
| database.
| slaymaker1907 wrote:
| One suggestion I have would be to include a very minimal
| implementation of login management (basically just
| properly hash/salt passwords and provide some easy way to
| add users). I've used Django before for the sole reason
| that it includes a database and user management because
| some API had to be login only since said API had high
| resource usage.
|
| I can see how having your own database is kind of
| "minimal" in the Java sense of the word. You don't need
| to install 50 different packages just to make a simple
| web app. There are minimal frameworks in the sense that
| they only provide a basic web server, but those are so
| minimal that you are forced to install a bunch of
| packages. It's minimal in the sense that create-react-app
| was minimal (RIP).
| 7ep wrote:
| Your wish is my command ;)
|
| https://github.com/byronka/minum/blob/master/src/test/jav
| a/c...
| pvorb wrote:
| Why is this under src/test/java?
| ljm wrote:
| What does 'minimal' even mean though? Code is code -
| either you pull it down as a dependency or you write it
| yourself, it all executes the same in the end.
|
| The minimal/zero-dep solution will have have bugs that
| have already been fixed or avoided by battle-tested
| libraries, and it will very rapidly lose minimal status
| as you start to build something serious in it.
| avmich wrote:
| > What does 'minimal' even mean though?
|
| It doesn't include the batteries.
|
| The batteries - extra features - weight you down if you
| don't need them. So you'd better be able to avoid them.
| Large projects can be hard to audit to remove things
| which could be nice and often useful - but just not in
| your case.
|
| Smaller projects have an advantage that you can easier
| understand them and decide what you need to add and,
| crucially, how to add that better, from your personal
| viewpoint. It's really hard to have nice, tiny,
| composable building blocks, so we have rather few
| attempts at that. Actually, a big part of programmer's
| education is teaching him how to properly write something
| which is well known, just have many small variations
| which depend on both requirements and some preferences.
| With a smaller project you can see those choices easier -
| and have better chance to correct them the way you need.
|
| > The minimal/zero-dep solution will have have bugs that
| have already been fixed or avoided by battle-tested
| libraries
|
| Maybe. Maybe not - you need to have all branches of
| execution checked, and with all possible input data
| combinations - and then all problems to get noticed and,
| crucially, corrected. Some problems, like unnecessary
| delays, can avoid e.g. representation in the logs.
|
| On the other hand, with smaller projects you have less
| moving parts and better visibility where, and how, things
| could go wrong. If you want ultimate reliability with
| proofs, you'll find it easier going with smaller
| projects.
|
| So, as they say, there are programs so simple they're
| obviously correct and so complex it's not obvious which
| errors they have.
| avmich wrote:
| > Code is code - either you pull it down as a dependency
| or you write it yourself, it all executes the same in the
| end.
|
| This looks like an oversimplification sometimes. You
| surely can solve the same problem in programming in
| different ways. An important part could be unstated
| assumptions you relied on when you wrote your code - and
| sometimes it's really important to understand those
| assumptions, or the code could strangely misbehave. "All
| executes the same" could literally be not true - some
| testing may suggest that, but more expensive testing,
| which is often not done, could show that for some unusual
| combinations the behavior is different.
|
| How do you know it's the same?
| schemescape wrote:
| I'm reading it as "minimal in scope". Scope creep tends
| to be a given for established/battle-tested libraries,
| and I'd argue that _over time_ scope creep could
| counteract security benefits of being battle-tested.
|
| Note that I'm not basing this on data, just on my
| intuition that a lot of major security bugs seem to be
| related to obscure/infrequently used functionality.
| kevincox wrote:
| Am I missing something or does the quickstart recommend an XSS
| vulnerability? String name =
| request.startLine().queryString().get("name"); return
| Response.htmlOk(String.format("<p>Hi there %s!</p>", name));
|
| Maybe having a little bit more available would be valuable.
| 7ep wrote:
| here's a more realistic example:
|
| https://github.com/byronka/minum_usage_example_mvn/blob/d649...
| kevincox wrote:
| Looks like that should be the example rather than promoting
| unsafe coding.
| ptx wrote:
| Making the user manually escape parameters (and be very
| careful not to miss any) seems at odds with the goals of ease
| of use and maintainability. Most template libraries do this
| automatically by default.
| 7ep wrote:
| You are not wrong. Just, here, priority is
|
| 1. minimalism 2. ease of use
|
| It's an uneasy balance. I am well aware of the value of
| fully-powered templating engines.
| schemescape wrote:
| For the record, I love this project's minimalist goal.
| Having said that, I agree with the other commenter that
| escaping by default (with an opt-out mechanism) is
| probably the better choice.
|
| I don't even think this violates your prioritization
| because it should result in less code when considering an
| app in its entirety (framework + logic).
| [deleted]
| tantamounta wrote:
| Your run of Apache Bench only specifies -c20.
|
| Please try this with Platform Threads - not virtual ones. It'd be
| very interesting to see the performance.
|
| (This should just need a 1-line change of the Executor?)
| msgilligan wrote:
| This is really cool to see. Congratulations!
|
| The existence of a project like this can lead to feedback that
| can improve other web frameworks and the JDK itself.
| theanonymousone wrote:
| Congratulations. I believe there is room for a micro framework
| that is smaller than Javalin or SparkJava.
|
| That said, if you want to cash even more on minimalism, you may
| want to provide a single-file example using JBang[0].
|
| [0]. https://jbang.dev/
| [deleted]
| jabradoodle wrote:
| Awesome, love to see more Java devs pushing back on the spring
| madness.
|
| In Db.java, with the write/update/delete locks, that mutate both
| in memory and on disk, is there not a bunch of race conditions
| there?
| revskill wrote:
| [flagged]
| galdosdi wrote:
| Actual Java dev here, not just someone who used it in college
| and got annoyed -- but I have no idea what you're talking
| about. Java has not been boilerplatey for a long time, I'd say
| since sometime between Java 5 and Java 8.
|
| You do know you can declare multiple classes in a single file
| (static nested classes), contrary to the popular convention,
| right? And "public static void main" doesn't count as
| boilerplate, that's like one line in the whole program...
|
| The real nice thing about Java is everything is statically
| typed, unlike in TypeScript where just your code and if you're
| lucky some of your dependencies BUT NOT ALL OF THEIR TRANSITIVE
| DEPENDENCIES are properly statically typed, and before you know
| it you've lost the nice safety and it's a crapshoot whether
| your type errors will really be caught, because a transitive
| dependency can do whatever it wants with your callback that you
| typed one way but it didn't care because it was plain
| javascript....
|
| This is why I am not a fan of either Typescript or PEP 484
| statically typed python. Typing works best when it was
| mandatory from day one, as long as there is some random untyped
| code in there somewhere nothing is really guaranteed.
| jen20 wrote:
| > The real nice thing about Java is everything is statically
| typed
|
| Optional and generics would like a word...
|
| Edit: OK, since this got a downvote, let me be clearer, with
| some help from the parent:
|
| You just use Optional<T>, and if you're lucky some of your
| dependencies BUT NOT ALL OF THEIR TRANSITIVE DEPENDENCIES
| also use Optional<T> correctly and don't return null, and
| before you know it you've lost the nice safety and it's a
| crapshoot whether your Optional<T> will be null.
| kaba0 wrote:
| I have never ever ever seen a null inside an Optional --
| the most common constructor actually Optional::ofNullable
| makes the correct decision, so you can't even fck it up,
| and if you deliberately try to, I'm sure intellij would
| scream your head off.
| jen20 wrote:
| The problem is whether the optional itself is null, not
| whether the contained value is.
| kaba0 wrote:
| That's not a problem either.
| galdosdi wrote:
| Yep, this is a great point, and while these days people use
| stuff like @NonNull/@Nullable, it does not help a lot, for
| the exact same reason.
|
| I wish Java had had non nullable types as default from the
| getgo, and it's hard to add now for the same reason JS/PY
| have a hard time adding static typing
| revskill wrote:
| You're correct ... in theory.
|
| At least in this project example code, i see tons of empty
| class like Result.java with empty content, on separate file.
|
| So is this normal convention for Java dev ? No eslint (or
| similar tool) to prevent boilerplateness ? That's my point.
|
| Do you Java dev have strict standard on prevent such things
| spread on all codebase, ecosystem,... ?
| peterashford wrote:
| I think the verbosity of Java is all in your head
| willsmith72 wrote:
| Yeah if I wanted to write for a JVM, I'd use kotlin
| 7ep wrote:
| Interesting you say that: https://github.com/byronka/r3z
|
| Basically the same thing as Minum, but in Kotlin.
| Dungenesst wrote:
| [dead]
| tofflos wrote:
| Good job on coming out of beta. It's crowded out there so best of
| luck!
|
| I think the initial README could do a better job of showcasing
| the framework. I think including the Maven coordinates and the
| quick start example instead of linking to other pages could be a
| step in the right direction. Check out the README I wrote in
| https://github.com/tofflos/undertow-examples to get an idea of
| what I'm looking for.
| smrtinsert wrote:
| I'm thinking of this as a nice programming exercise for the
| author. As for being a framework which promises more with less,
| that only holds until feature x is required.
| 7ep wrote:
| a perfect example of the thinking behind most frameworks. I
| don't think most people are looking for minimal. For those that
| are, this might be right up their alley.
|
| Minimalism is an interesting ideology. it's about choosing to
| do more with less, and there's a great deal of ingenuity in
| saying, i only have this one knife and a rope, how do i cross
| this chasm. so to speak.
|
| no offense intended to the batteries included crowd. this is
| just something i have developed a taste for.
| JackFr wrote:
| Your kind of playing a little fast and loose with the term
| 'database'. You've implemented a naive persistent cache.
| (Don't get me wrong, I have too at times. they can be quite
| useful.)
| 7ep wrote:
| I'll accept the naive mantle. But is this not a database? A
| database is an organized collection of structured
| information, or data, typically stored electronically in a
| computer system.
| shrimpx wrote:
| The 'batteries included' space is definitely a market. For
| example https://streamlit.io is wildly popular with data
| teams for quickly making a pre-styled, usable enough web UI
| to put on top of some model, with controls that are
| automatically reactive. Those ppl have zero interest in
| fiddling with modular systems or spending time optimizing and
| scaling web apps.
| quickthrower2 wrote:
| Modularism is my favourite. I am enjoying using ExpressJS of
| all things, because it comes bare bones but you are a few
| mix/match middlewares from having it set up as you like. And
| the process of setting them up is not a chore, it is
| valuable, you now know how your thing works. Whereas
| frameworks give you the kitchen sink behind a facade that
| makes most happy paths easy. But eventually you have to deal
| with that complexity one way or another, and usually it is by
| hacking together stack overflow and github issue answers :-)
___________________________________________________________________
(page generated 2023-09-25 23:00 UTC)