Ask HN: What stack would you use to build a CRUD web app on the JVM today?

157 points by networked ↗ HN

212 comments

[ 7.4 ms ] story [ 226 ms ] thread
Why are you tied to using the JVM?
Because of Scala, in my case, and because I can run React.js server side in the JVM. And because it's fast.

Edit: Oh I misunderstood your question. (Did you perhaps edit your comment, added "tied to"? Didn't notice that the first time)

I second Play Framework. Have used it and Scala is a very nice language to learn. If I had invested in so much into the JVM, Play Framework would be it. But, if it's just a simple CRUD app, and if you had a choice, I'd recommend you to give Ruby on Rails a try. Hope this helps!
Scala and Play is a great choice. Another good Scala framework is Lift: http://liftweb.net/

If JVM is not a must, consider using Meteor.

+1 for Meteor. We've been using Meteor for about 8 months now and are amazed with the productivity and no-boilerplate code. To give some context, we were previously a JVM-only shop. In the past we've used Spring+Hibernate+GWT for one project, Ninja for another project, and a full blown custom stack + Dojo client side in a third project.

If JVM is your only choice because you want to connect to legacy Java API, consider wrapping the Java API with REST interfaces and use them with Meteor.

How do you find the GC/profile/coverage/tuning of the server side node process compared to the jvm?
TBH, we didn't have to do much performance tuning. The Meteor app we are building is heavy on the database CRUD (like real heavy) so there is not much to tune code-wise other than define good data structures for your db. And really, if you have to do any GC tune up for your node app, you really have to ask yourself if there's something you could do instead in your code first.

I must admit that initially it seemed that node js profiling sucks, but it's just that we are still not used to the internal intricacies of V8. When we did profile a couple of times (we use Webstorm so just used flag in the run config), there were too many things out of the context of our code showing up. I think if you show a snapshot of YourKit to someone who hasn't worked with JVM before they would have a similar reaction.

Lift works well but is utterly incomprehensible. Play is better written and maintained.
I agree with Play/Scala combination. Play is light enough for simple tasks, but at the same time it's a feature-complete powerful beast - built on Akka and capable of potentially handling millions of requests.
I agree. And I'd add that the continuous compilation of the Play framework allows for a great, fast workflow. Even in combination with non-JVM compilation like for Typescript.

The last version comes with Slick integration which brings Ling-for-Sql style persistency to the JVM. In combination with support for Postgress JSON persistency that makes for a great fast prototyping stack.

I highly, highly recommend squeryl over slick. Much more readable as you're basically writing SQL in scala; you don't have to translate constantly between orm methods and SQL.
Agreed. Squeryl provides a really easy and intuitive API for querying and updating data. Slick seems to be less easy to use.
I second Squeryl over slick.Had a very nice experience.
If you're looking for a Play-like framework but that's just Java, not Scala, you could check out Ninja Framework. I tried it for a simple CRUD app last year and it worked out pretty well. It's not as widely used or as maintained as Play though (+Play does have a Java API).
Glad to see support for Scala/Play sprinkled throughout the responses here. I love working with both. Now I'm considering taking the next step and adopting ScalaJS for some small internal apps.
I made the ScalaJS leap. Good for all my internal JS stuff. Interfacing with legacy JavaScript libs sucks (similar problems to using Typescript).
I don't agree because 1. Play!2.x is asynchronous, and you need to find NIO-compatible libraries, 2. I like Jersey for REST resources better than Play!2.x's "routes" file. I had to build a stack this year for an app which needed to share code with another Spring app. I've chosen DropWizard because I could share the Jersey resources and I didn't have to learn everything again.
You do not NEED to find NIO libraries. It sure helps, yes. But it comes with a wrapper of a webservice library, and slick does the RDBMS nicely (and offshoots like phantom to do cassandra, etc).
On the server: Spring Boot + Spring MVC + Spring Data + Gradle

On the client: React

This is like the software engineering equivalent of someone who only wears Nike clothes.
Clojure + ClojureScript + Reagent/Om as an abstraction on top of React
Spring Boot backed with Postgres and Maven to wrap it all up. Spring Boot is really years of distilled knowledge of creating web servers in Java. Its opinionated but for good reason; you'll very quickly get everything you need for a RESTful API and there's extensions for almost everything you'd need. Need to work with websockets? Just add a few lines to your POM. Need scheduling? Include an annotation on your main class. It really is a solid framework.
If you're favoring Boot, why not just use a newer version of Grails?
I don't understand the question, beyond the fact that Spring and Grails both had the same corporate sponsorship at one point in the past.

Spring Boot is a rapid, flexible, and fairly tight (as far as Java frameworks go) foundation for building Java applications. Grails is a Groovy-based wrapper layer around Spring and Hibernate.

So if you want to use Groovy for application development, then Grails is certainly there for you. However, I don't think it's the most competitive option. I think Groovy's great as a scripting language, and I use it for things like automated testing, but I wouldn't enjoy using it for primary application development because it's not a statically-typed language.

Although recent versions of Groovy allow you to designate typesafe "areas" within your code, it is still fundamentally non-typesafe. Because of this, tooling is always going to be weaker than it is for typesafe languages. IntelliJ is probably the best Groovy IDE out there, and it's still frustrating to work with because it can't detect autocomplete options most of the time.

If you're doing development on the JVM in the first place, then odds are you favor static typing. Plain Java, or Scala, or most of the fringe options like Kotlin or Ceylon. If you're in the minority camp who want to use a language with dynamic typing, even THEN there are better options than Groovy for application development. JRuby has a much broader and more active community, and Clojure will give you more "Internet cool points" on HN or Reddit or wherever.

Finally, the last time I looked at Grails, it was FAT. Building an application took forever. I'm sure they've (hopefully) optimized or rebuilt things since then. However, since it's a wrapper around Spring and Hibernate, it's never going be any lighter or faster than Spring and Hibernate.

I don't mean any disrespect to Groovy. I've been using it forever, and it comes in handy with certain use cases. However, it's primary niche is being the dynamic JVM language that most "enterprise" shops have become comfortable with... and so if you're trapped in an "enterprise" shop and are dying to use something other than plain Java, it's the thing you'd most likely be allowed to use.

For the most part you don't need to rebuild to test your changes. Live reload works.
how would you compare it with something like Dropwizard or Undertow.io ?
Spring MVC + Hibernate. I'm familiar with those libraries and they provide almost everything I usually need.

For frontend I would choose either JSP or Thymeleaf, both are good, depends on your taste and whether you're writing HTML markup. Another option is a JavaScript-powered SPA website. You have plenty of choices there.

And I highly suggest using Intellij Idea Ultimate + JRebel. Those technologies provide tremendous productivity boost and I can't imagine working without them. Though they are not free (AFAIK you can get JRebel for free).

I attempted to learn Spring framework about a year ago since I wanted to build a quick CRUD app on the JVM too. However, I found the Getting Started guides really difficult to learn from. In addition, I found myself quite confused as to which templating engine to use and how to use it in Spring. I stopped working on CRUD for other reasons (pursuing an MSc where I mostly wrote C code).
Yep, similiar situation here. The getting started guides often just introduce a single concept and stops there. Many seems outdated as well. However, Spring Boot with whatever DB choice you make is a winner imho. Found it really easy to get going after just investigating a sample project.
For people whose impression of Spring and Hibernate was formed a decade ago, its really worth another look now. You can completely manage them with annotations in your code and lots of the boilerplate will be generated for you based on naming conventions.

JHipster (https://jhipster.github.io/) provides a Yeoman generator to make a basic project template as well as generate entities and screens using an Angular, Spring Boot & Hibernate stack which makes it super easy to get started with all of these components.

An open source alternative to JRebel is https://github.com/dcevm/dcevm - it works great with Java 8, Intellij, Spring & Hibernate.

It doesn't change my impression much if the answer to "lots of boilerplate" is to use another tool to generate it automatically...
Actually the example I was thinking of is the finder methods which require only an interface definition conforming to a naming convention. Bytecode is generated at runtime - there is no generated source to manage.

Not much of what Jhipster generates could be considered boilerplate - the application code is pretty DRY. I've used Rails off and on since 2005 and it is fairly comparable in that respect at this point though Java is more verbose of course.

It's difficult to take Spring seriously after trying Jersey. Resource traversal is a powerful concept. Also, recent or not, Spring still comes with way too much complexity and magic. I'd really go for something more Sinatra/Flask-like. Haven't tried Dropwizard, but from what I saw it looks a lot more sane.
> It's difficult to take Spring seriously after trying Jersey

I'm using Spring Data REST at work. We have a dozen endpoints. We've had to write code for one of them.

The rest were generated by introspecting our models. Complete with HATEOAS links, sorting, searching, paging and HAL. It made a whole bunch of work simply disappear -- even compared to Rails.

Yeah, as long as you go with Java 8, then I think the Spring+Java app is still a viable and also pretty powerful option. Although I disagree about Hibernate as I've found it ends up causing a lot more problems than it solves in the end.

Java + Spring is still a very safe (albeit boring) option for a lot of different types of web apps today.

+1 for getting rid of hibernate (and JPA et al). We've been mucking around with JBDI recently it really seems to work well. We haven't done anything extravagant yet, but initial impressions are good
Jersey + Hibernate for a RESTful service. AngularJS in the frontend
Definitely Clojure with http-kit [1]. Easy to use, minimalist and supports websockets.

However, it depends from your use-case. Could add some detail please?

[1]: http://www.http-kit.org/

That looks like it is a HTTP server.

What parts of CRUD does it help with, does it have say an ORM (or equivalent way to interface with a database) and some sort of default interface so the user can work with it?

I used to be a big fan of http-kit, but it seems like it's not maintained anymore. I've since moved on to Immutant 2, which seems to offer much more. The primary difference between Immutant 2 over 1 is that it's not monolithic and you can just import what you need. And I believe it's faster too.

Also, yesterday I announced that I am writing a book on developing REST API's in Clojure, if anybody's interested in learning: http://christopherdbui.com/announcing-practical-rest-apis-in...

I can personally second this. It is pretty quick to get a micro service up and running with Clojure. My team has been using the Duct[0] generators which set up a nice scaffolding. It also includes some decent examples writing components, models and endpoints. Plus swagger is free out of the box.

[0]: https://github.com/weavejester/duct

Java spark or vertex + hiberate or sql2o + freemarker
Also agree with the combination of Play + Scala for flexibility and ease of use.
Grails, I really like Groovy as a language. Grails provides a lot out of the box and is good enough performance wize for small to medium sites with no tuning.
this is a comment posted yesterday criticizing the management of Groovy - https://news.ycombinator.com/item?id=10293508
Meh... vorg posts on nearly every thread that mentions Groovy and rants about all the perceived wrong-doings in the Groovy community. Some of his points have some merit, but he seems to tend to make mountains out of mole-hills.
You didn't comment on any of the specifics mentioned in that linked-to comment, instead you attacked my behavior, just like one replier to that comment.

You mentioned Groovy moving to the ASF in another comment above, but if only two people control the DNS name and physical access to that server in Germany hosting the websites, receiving the Nabble mail archive and Apache website redirects, creating the phantom downloads from Maven and Bintray, etc, then the list of committers and mentors at ASF for Groovy is meaningless. Because Groovy isn't really protected by the ASF guidelines, its future is uncertain.

As for Grails you also mentioned, Grails 3 also has an uncertain future, what with so few people upgrading from version 2, just like with Python version 3. Grails 3 bundles all of Gradle, and its business case seems less about modernizing Grails 2 than about its founder wanting to muscle in on the Gradle consulting market, just like he did with Spring in Grails 1, until SpringSource bought his company to protect their cashflow. He's trying the same with Gradleware.

instead you attacked my behavior, just like one replier to that comment.

Have you considered that your behavior might be at issue then? Seriously man, you seem to go out of your way to find any and every thread that mentions Groovy in any way, and then launch into your rant about all the evils of the Groovy community.

The thing is, I said that you have some merit in what you say. But the repetitiveness and the vitriolic presentation make you look like somebody who has an axe to grind or something, instead of a dispassionate observer.

You mentioned Groovy moving to the ASF in another comment above, but if only two people control the DNS name and physical access to that server in Germany hosting the websites, receiving the Nabble mail archive and Apache website redirects, creating the phantom downloads from Maven and Bintray, etc, then the list of committers and mentors at ASF for Groovy is meaningless.

When existing, long-established projects move to the ASF, they always deal with shit like this. It takes time to sort this stuff out, that's why there's an incubator. And if it doesn't work out, then so be it. At that point, I'd reconsider my position of advocating for Groovy. But I'm not going to rush to judgment and focus on all the negatives, which is what you seem to do.

> you seem to go out of your way to find any and every thread that mentions Groovy in any way, and then launch into your rant

The most significant thing you've really said here is that I generally post comments under my own name, as I suspect you also do, given how active your "mindcrime" user is and the implicit assumption in your above comment that you're seeing the entire picture by looking at who's posting comments. Have you considered that other "entrepreneurs" involved with Groovy keep hundreds of HN logins each to obfuscate their mischief here and engage in illicit surveillance of people whose comments they don't like? This I don't say in my comments, instead I keep what I say seemly and do it in my own name. It's because I use my own name that I "seem to go out of my way to find any and every thread ..."

Have you considered that other "entrepreneurs" involved with Groovy keep hundreds of HN logins each to obfuscate their mischief here and engage in illicit surveillance of people whose comments they don't like?

Honestly? No, the thought never crossed my mind. And now that you mention it, it doesn't sound terribly likely to me. Not "hundreds* of such people anyway. Maybe two or three. Why do I say that? Simply because Groovy just doesn't come up that often to begin with. And a decent percentage of the time, when it does, I'm the one bringing it up, and know where I stand. And while "mindcrime" clearly isn't my birth name, my HN account is clearly linked to my real world identity, so no one can really claim that I'm trying to hide anything here.

One other person here to mentions Groovy / Grails occasionally is @mgkimsal, and I also know him in the Real World, and have no suspicion that he's up to anything nefarious.

That said, people never cease to surprise me and clearly some people post on HN largely for commercial gain. I don't think anyone questions that. I just don't see what you seem to see, in terms of large numbers of users here trying to manipulate the discourse around Groovy in particular.

> other "entrepreneurs" involved with Groovy keep hundreds of HN logins each

> post comments under my own name, as I suspect you also do

I would agree probably 2 or 3 people -- I never said "hundreds" of people, and I specifically said you post comments under your own name, not the opposite.

ReactJS + DropWizard + JDBI (or JOOQ) if you like JAX-RS.

ReactJS + Spark framework (or Vert.x 3 or Ratpack) + JDBI if you don't like JAX-RS.

I don't like JAX-RS, but it is hard to beat DropWizard if you do.

(comment deleted)
Play Framework (Java or Scala)
It depends.

If I were to work mostly alone on a smaller project, I would use clojure/clojure-script, because I used it at my work for a year and really liked it.

If I were to work with more people, I would first ask them.

Do they have dislike for dynamic typing? Scala+Play sounds good.

Are they really comfortable with EE java? Spring MVC + Hibernate + JSP ... e.t.c

i recently wrote a small blog engine in vert.x (http://vertx.io/). i'm not fluent with reactive programming yet (so i didn't use RxJava), but the callback hell was manageable enough. among the upsides are the seamless integration and handling of websockets. the blog engine is a bit of an outlier though because it's embedded and fully single threaded. there are a lot more advantages if you leave out the embedding, like several more languages (several languages with interpreters available on the JVM).
I would recommend vert.x too.

But only because I'm used to nodejs and this is the jvm equivalent.

Vert.x is fantastic.

My honest opinion is that JVM folks love complexity though. It's a mix of popularity, job security and good marketing that allow the traditional bloat-powerhouses to remain popular while technologies like Vert.x remain criminally under-utilized (see the rest of this thread for evidence). I don't know how or if this will ever change, but the downside for the JVM ecosystem overall is that people associate the JVM with things like Spring and Hibernate rather than things like Vert.x. And that's a shame.

StrawBerry on Beryl as backend and Torque or Glass as frontend
I'm building something with React + Relay + Sangria and it's working out well so far. There's a sample sangria project showing how to use it on akka-http, and if you write a pure web app like this, you could serve the javascript client from somewhere dumb like S3. Plus with this stack you can plug in react-native apps as well once your server is written.
how are you running React on the JVM - Are you using Nashorn or Rhino here?
Sangria is scala. React is the client in the browser. That doesn't run on the JVM.
can you talk a bit more ? How do you write your views and integrate them with sangria. I'm coming from nodejs .. where everything is JS, so I'm trying to understand how this stack works.
Sangria is a scala GraphQL server. Facebook released an initial reference implementation in javascript, but I wanted the type-safety that scala gives. If you're more comfortable with JS you could check that out. See https://facebook.github.io/relay/.

With GraphQL you don't write views per se, but you make data available. The client can pick and choose which of the exposed attributes it needs to render a view. So if you have, say, a user profile page, you might use relay to declare that you need something like:

    user(id: $userId) {
      username
      age
    }
Then relay will hit your graphql server and add this data to your react props.

It's a similar thing with mutations - you expose operations through your server and then relay handles calling it with the necessary data, and propagating back the response into the UI.

I've found this approach to be very powerful and quick to develop in (once I got my head around it). With REST, you have to keep on adding new endpoints or fiddling with your server if you need more attributes from it. E.g. say you also want the user's gender. With traditional REST you'd need to make this change in your client (to request that extra data) and update your server to expose it. Or perhaps you'd add a new endpoint that returned more data about a user. Then you may also need to decide what happens with legacy clients. Should they fail if they receive extra, unexpected data, or do you version your API, etc.?

With GraphQL you can choose to expose all of the different attributes on your user model (with authentication/authorisation, etc as appropriate) in-advance, and then if clients need the gender, they can just request it via relay.

After I tried writing an app using REST and continually feeling like I was walking in mud, this is a real breath of fresh air, and I feel productive again. I definitely recommend checking it out.

thanks for that!

I'm assuming your views are written in React.js - how does that get served to your clients ? does the Scala relay server serve it ... or do you have a separate client webapp ?

Yeah the views are all just react.js. The JS for the webapp is dumb so can be served by S3 (i.e. no server-side rendering). It's basically REST++ - a pure server that just serves data (sangria/graphQL server) and a decoupled client (which in my case happens to be a react web app for now).
Not really related, but Nashorn is dead to me now that I've found J2V8.
I would not start with technology stack and build around them. You look at your use cases and build out. Pick your frameworks and databases judiciously and as late as possible.

Read: https://blog.8thlight.com/uncle-bob/2012/05/15/NODB.html

Read: http://www.amazon.co.uk/Growing-Object-Oriented-Software-Gui...

[EDIT] Removed the unnecessary/unhelpful opening statement.

Particular things have to be decided upfront. You can't just add an app framework as an afterthought to your code.
I'm unsure about that and I think it depends greatly on what is the goal.

You can very easily do DI without Spring. (yes I know Spring is more than DI) As the project grows you can simple add Spring if brings 'real' value.

You can defer the choice of data store very late in a project without hinder its progress.

I'm not anti-framework/tooling, I just want to make sure it is required before I add it.

Most, if not all, frameworks require some specific bootstrapping/configuration that is extra to the job at hand.

Just because uncle Bob says something doesn't mean it's true.

Frameworks and stacks provide templates for building CRUD apps. Building CRUD apps (read: database skins) isn't a big technological challenge most of the times anyway. So picking a stack that abstracts most of it for you could be a great help to only focus on the parts you care about.

Not every project requires astronaut architecture and grand design. Half the internet runs perfectly fine without these considerations.

Scaffolding a project through the tooling of a framework (tooling matters!) and having something up in a day instead of philosophical debates about your data is huge. Having something up in production super fast because you didn't stop to think about architecture is perfectly fine for 95% of software projects that are just CRUD.

My inclusion of these two reading resources were only meant as examples. The reader is still required to make their own mind up.

I haven't suggested astronaut architecture; the question didn't indicate the size/scale/importance either.

50% of the internet runs perfectly fine without consideration...wow! Have you looked at all the source code yourself to make such a ridiculous conclusion.

Tooling does matter, but I'm suggesting the point of focus to start with is the requirements.

As a data point, 20% of the internet runs WordPress [1], think these people spent a lot of time thinking about architecture.

A lot of time the problem being solved is in fact simple enough and easy enough to solve without thinking about architecture, not everything is a hard problem - and there is nothing noble about solving things over and over.

The point I was disagreeing with was "Pick stacks as late as possible". If you have a large project by all means do that, if you're just building a REST API in microservice architecture, or you're building a blog or something that's fairly simple to model - you're perfectly fine picking a framework you like first.

[1] http://w3techs.com/technologies/overview/content_management/...

I'll skip the flame about WordPress developers as I don't know any, or, viewed their work.

If you think building micro service architecture can be done without consideration I'm lost for words.

The question–as I've been rightly reminded–was 'CRUD Web App in JVM'; furthermore, we now know that the domain part of the application is already done, so my comment is moot.

That just leaves CRUD, Web, and JVM.

He did start with the use case -- "a simple CRUD app".

That is sufficient to start looking for a framework, in my opinion. Cases where that is wrong aren't simple.

It seems to me that you intentionally misrepresent the argument to make it easier to attack. No one is claiming that Uncle Bob is always right or that an "astronaut architecture" is the correct design.

On a different note, I would also recommend to not start picking the framework or stack: Instead I would start by creating a couple of basic classes that represent the business logic.

I would also write tests for those classes. Furthermore I would probably introduce some repository classes that would interface with the database. Lastly I would try to find a library that handles HTTP routing - if the CRUD app was meant to have an HTTP I/O channel.

Not everyone wants to "go fast and break things" or blindly let their codebase depend on a third-party framework. This is usually what ends up happening when you don't think about architecture.

Check out the most popular Angular posts on HN this year [1]. Notice a trend?

[1] https://hn.algolia.com/?query=angular&sort=byPopularity&pref...

I would start by creating a couple of basic classes

How would you do that without deciding on a language/framework?

Suppose the goal is a shared calendar and message boards plus some way to buy ski passes. Doing this using SharePoint is going to be vastly different than Ruby on Rails.

Yes/No, depends on many factors IMHO. Mostly on the person/team that needs to build/use it.

We know nothing of OP's case so the best thing we can do is trying to answer his question instead of answering to go read some lengthy book.

OP might be in a team that needs to develop an API for a product that will be deployed to millions of people(I doubt it) or could be someone that just wants to know what is the current fashion to develop a CRUD application while learning a new stack that is up to date.

In the first case, you might want to learn more of the situation you are in and pick around that. In the second case, there is nothing wrong with just picking one and hacking away.

fair comment. I will add though, spring, or hibernate, or play, or [pick your framework here] will also require reading.
I think "JVM Web app that does CRUD" is sufficiently narrow to consider that your use case, and pick a technology based on that use case.
(comment deleted)
For context, I already have a JVM application that handles the business domain. Adding a CRUD user interface (and, coincidentally, a database) is the next step I have in mind for its development. However, I didn't want to state those constraints in the OP because I wanted the answers to be broadly applicable.
The OP listed the following requirements:

"simple CRUD app"

That is more than sufficient to pick a framework/database and start working. I'm not sure how many simple CRUD apps you have built, but the challenge tends to come when you put them in front of users who can't figure out the interface. Consequently, I'd argue to choose a framework quickly and get it in front of a user as fast as you can.

Definitely Spring Boot with spring-data (if it supports your database/nosql system) since you're going to do a CRUD app, it will manage a lot for you. Add it spring-data-rest and you've got your models exposed on REST for free. If you want to secure some REST operations, spring-security got you covered.

Then on the client side you can add some hype using React or what's hot at the moment. Joke aside, on the server side Spring is solid, the whole thing is well engineered and it got you covered on every aspect of this kind of app, and then more.