In my opinion Spark:
get("/hello",(request, response) -> {
return "Hello World!";
};
is still uglier than jax-rs: @GET @Path("/hello")
String hello() {
return "Hello World!";
}In my opinion Spark:
get("/hello",(request, response) -> {
return "Hello World!";
};
is still uglier than jax-rs: @GET @Path("/hello")
String hello() {
return "Hello World!";
}It emulates Sinatra for Ruby, which takes that 'clean' approach of doing things simply and predictably. You can very quickly understand how to use annotations with jax-rs. But that's declarative. You annotate your code, and understand that the framework will take care of the rest. This is great for fully built complex frameworks. The problem is, that with annotations you are marking something in a very ambiguous way that can be used by the framework in any way. Its easy to understand, but from just reading the code, you can't really know HOW the annotation is being used.
Sinatra/Spark on the other hand are much more imperative. You need to assume very little about what the code actually does, as you are imperatively building exactly the way you'll be listening to requests, without having to know anything of how the framework is going to interpret anything. It's much more direct in what you wrote mapping to a very specific predictable set of actions, determined by the language, not so much the framework.
Two separate ways of thinking/styles that are happy to live separately making people happy in different ways.
Honestly, when JUnit was still "just Java" by that definition, it was a much worse framework.
Annotations in Java have always bothered me! Why are they needed? I don't need them in Clojure, Go, Haskell, C - similar behaviour is supplied by alternative means.
...So any sufficiently advanced magic is indistinguishable from science :)
With plain functions if I need to wrap requests or responses I just wrap the functions. With JAX-RS I need to find or write an appropriate annotation or start adding filters.
With plain functions I can share behaviour between resources by sharing functions.
I love how simple it is, but my company is at the point where squeezing every ounce out of our API servers is necessary. I've been fiddling around with Vert.x a little; but another option is just to use raw Servlets.
Read this to get some idea of what can be achieved with annotation processing: http://scg.unibe.ch/archive/projects/Erni08b.pdf
They do use so compiler API which are not stable interfaces, but even without that, you can go surprisingly far.