I like Jersey (and the standard API it implements: JAX-RS) a lot on its own (as compared to using a larger framework like Spring). However it can be difficult to program imperatively.
You'd expect in a compiled language like Java you'd figure out most of your bugs during the type-checker pass. But there's so much implicit structure, class loading, and annotations that make Jersey apps mostly dynamically typed. You've got to compile and then hit every API endpoint/middleware to know it's registered at all.
Even when you find the explicit APIs they are cumbersome to use, requiring many lines of code for something that should be simple like imperatively registering a route.
I put together my own notes on using Jersey, JOOQ (an ORM), and PostgreSQL a month ago. My aim was to be as explicit as possible (though I did still have to fall back on class loading a few times). [0]
It's a vanilla implementation of JAX-RS. The rest of the libraries are lightweight wrappers of JAX-RS with few committers or massive wrappers of JAX-RS with a lot of development overhead. JAX-RS on its own is mostly at the right level for me (with the exceptions mentioned).
I know these kinds of tutorials are just for getting a flavor of a framework or paradigm. Nice so see it.
As someone who's used Mongo for nearly a decade, I always feel compelled to note: Mongo will NOT scale with relational data like this. Sure, it can handle a lot of records. It'll have fast basic inserts or queries. It can scale with replicaSets and sharding. But it is NOT designed for relational data. Doing relational data is so painful in Mongo, with any sort of scale. Save yourself so much migration headache by using a "regular" SQL database, until it doesn't work (rare).
It should probably go without saying that most distrubuted solutions this days typically have several types of data stores in use: I'm using Postgresl, Redis, and Mongo all the in the solution for the appropriate use cases....
Jokes aside, I had to do some analytics work at my last job, off data that was on Mongo (arguably with no good reason, other than it being 'web scale'), and it was a major pain.
We actually thought Mongo can be a problem for relations, but opted for it since we are used to it’s comfort of use.
Can you recommend any good Java SQL libraries that automatically handle table creation and migrations?
We’re so used to having those options it’s hard to go back to writing queries for the DB to do all that.
Have a look at liquibase and flyway. Personally I love using flyway together with jOOQs' code generation (concretely, running the migrations against a docker db container during build, and code-generating the entities/records then based on it).
Can you help me understand what you mean by relational data? The only issue I see with Mongo is if you have many simultaneous updates of a single record, then there is lock contention.
I really like Kotlin for full stack development. Unfortunately most shops are still using Spring. Which I feel really limits the languages potential. I've ended up on Vertx, but I am a bit concerned about it's lack of traction.
* Routes can be based off Open API (contract first), or a simple route via string
* First class GraphQL support
* Full ecosystem for DB, message bus, etc.
* PolyGlot, with a message bus and bindings for a number of different languages.
* For data persistence I use JaSync with a custom micro-orm, noted below. This provides non blocking async support.
With Kotlin multi platform, and typescript definitions in alpha. I can generate the data classes to a typescript interface. Have my react project pull those in, and use the data. If I need to do pub/sub over web sockets into react that's also supported by Vertx. This drastically reduces bugs, and developer time. As the data models are directly incremented and released with the back-end. The front-end doesn't have to write additional code. The Typescript project does need to install a kotlin dep, but that gets minimized. A few kilobytes to ease development inter opt is worth it. The message bus also does pub/sub to iOS/Android.
I've switched to kotlinx serialization. I have some parts running on native llvm+clang, graal/jdk and nodejs. So I need the modules to be easily serialized on different platforms.
This scales from a simple monolith. To if I need AOT compilation to Graal then running through KNative. I generally start projects as a hybrid monolith. But found it's scaled really well.
I'm really excited for the compiler api / arrow meta compiler. I'm looking into ahead of time compilation of the queries. Automatically generating data classes for more advanced queries. Think joins, or json aggs. Additionally compiling the ORM calls into actual SQL strings.
* Multi platform kotlin micro orm (MariaDB + Postgres) only right now. Closest JDK analogy is Jooq.
A few years ago, I was really impressed with Vertx and wanted to use it for a project. I was also into alternative JVM languages for awhile.
I feel like Java keeps getting better and better and the compelling argument for the alt JVM languages is getting less interesting. (Except for something like Cloujure which still looks super interesting to me.).
Thoughts from someone whos worked with Groovy/Grails, Scala/Play, Jython, and Kotlin....
I thought so too, that Java will close the gap eventually and have data classes etc., but the truth is that Kotlin is quite a different language because it has a different philosophy (developer ergonomics, stronger functional style support, first class functions, immutability), and some things cannot be fixed in Java (NPE, static keyword, generics, operator overloading).
> I feel like Java keeps getting better and better and the compelling argument for the alt JVM languages is getting less interesting
I keep going back to Java optimistically thinking the major problems will be solved but it's always hell compared to coding in Kotlin or Groovy (which I switch back and forth every couple of days). While it's true some fundamental things have been addressed, there's just so much missing from the ergonomics of Java that it is syntatically constrained from fixing, and philosophicaly poorly positioned to address.
I agree with you. I think the next few JDK versions will bring back a lot of java devs. There was even a talk at the recent kotlin conf around it.
A lot of the back-end Kotlin I see. Is really java lite. A lot of the beneficial features I see of the language aren't really being used. At that point, why not just use Java?
I make use of a ton of features outside of Java. But I'm a very small minority from what I've seen.
I recently converted a spring project to use ktor+konform+exposed after frustration with the number of errors that were not getting caught at compile time.
Having mostly eliminated decorators & code generation I find my development experience much more streamlined.
26 comments
[ 0.24 ms ] story [ 110 ms ] threadThe string interpolation in findById will open up your whole database to the world, possibly even allowing remote command execution.
Same for the other functions that access MongoDB.
Do not copy / paste random code until you fully understand it.
No, I'm pretty sure that's fine. findById takes an ID, not anything else or any type of query.
You'd expect in a compiled language like Java you'd figure out most of your bugs during the type-checker pass. But there's so much implicit structure, class loading, and annotations that make Jersey apps mostly dynamically typed. You've got to compile and then hit every API endpoint/middleware to know it's registered at all.
Even when you find the explicit APIs they are cumbersome to use, requiring many lines of code for something that should be simple like imperatively registering a route.
I put together my own notes on using Jersey, JOOQ (an ORM), and PostgreSQL a month ago. My aim was to be as explicit as possible (though I did still have to fall back on class loading a few times). [0]
[0] http://notes.eatonphil.com/a-minimal-rest-api-in-java.html
Javalin, Jooby, Spark, Micronaut and more, what do you like about Jersey over these ones?
As someone who's used Mongo for nearly a decade, I always feel compelled to note: Mongo will NOT scale with relational data like this. Sure, it can handle a lot of records. It'll have fast basic inserts or queries. It can scale with replicaSets and sharding. But it is NOT designed for relational data. Doing relational data is so painful in Mongo, with any sort of scale. Save yourself so much migration headache by using a "regular" SQL database, until it doesn't work (rare).
Jokes aside, I had to do some analytics work at my last job, off data that was on Mongo (arguably with no good reason, other than it being 'web scale'), and it was a major pain.
That was its purpose, and I think that's beautiful.
* Routes can be based off Open API (contract first), or a simple route via string
* First class GraphQL support
* Full ecosystem for DB, message bus, etc.
* PolyGlot, with a message bus and bindings for a number of different languages.
* For data persistence I use JaSync with a custom micro-orm, noted below. This provides non blocking async support.
With Kotlin multi platform, and typescript definitions in alpha. I can generate the data classes to a typescript interface. Have my react project pull those in, and use the data. If I need to do pub/sub over web sockets into react that's also supported by Vertx. This drastically reduces bugs, and developer time. As the data models are directly incremented and released with the back-end. The front-end doesn't have to write additional code. The Typescript project does need to install a kotlin dep, but that gets minimized. A few kilobytes to ease development inter opt is worth it. The message bus also does pub/sub to iOS/Android.
I've switched to kotlinx serialization. I have some parts running on native llvm+clang, graal/jdk and nodejs. So I need the modules to be easily serialized on different platforms.
This scales from a simple monolith. To if I need AOT compilation to Graal then running through KNative. I generally start projects as a hybrid monolith. But found it's scaled really well.
I'm really excited for the compiler api / arrow meta compiler. I'm looking into ahead of time compilation of the queries. Automatically generating data classes for more advanced queries. Think joins, or json aggs. Additionally compiling the ORM calls into actual SQL strings.
* Multi platform kotlin micro orm (MariaDB + Postgres) only right now. Closest JDK analogy is Jooq.
https://animusdesign.gitlab.io/kotlin-frm/#/./sql
Editing formatting
I feel like Java keeps getting better and better and the compelling argument for the alt JVM languages is getting less interesting. (Except for something like Cloujure which still looks super interesting to me.).
Thoughts from someone whos worked with Groovy/Grails, Scala/Play, Jython, and Kotlin....
I keep going back to Java optimistically thinking the major problems will be solved but it's always hell compared to coding in Kotlin or Groovy (which I switch back and forth every couple of days). While it's true some fundamental things have been addressed, there's just so much missing from the ergonomics of Java that it is syntatically constrained from fixing, and philosophicaly poorly positioned to address.
A lot of the back-end Kotlin I see. Is really java lite. A lot of the beneficial features I see of the language aren't really being used. At that point, why not just use Java?
I make use of a ton of features outside of Java. But I'm a very small minority from what I've seen.
Having mostly eliminated decorators & code generation I find my development experience much more streamlined.
Kotlin DSLs are really nice to work with.
And this is why platform languages win, there is nothing to spend time "making it work".