
A Sinatra-inspired micro web framework for Java - codenut
http://www.sparkjava.com/
======
pron
This project is nice but it's important to mention that there is actually a
"Java micro web framework" standard called JAX-RS that is pretty widely
adopted (with solid open-source implementations by JBoss, Apache, Oracle and
others). Here's a rather old comparison of JAX-RS implementations:
[http://www.infoq.com/news/2008/10/jaxrs-
comparison](http://www.infoq.com/news/2008/10/jaxrs-comparison)

Its most notable implementation is perhaps Jersey
([https://jersey.java.net/documentation/latest/getting-
started...](https://jersey.java.net/documentation/latest/getting-
started.html)), which is used, for example, by Dropwizard (mentioned in
another comment).

Some of these implementations include important features like health and
performance monitoring.

~~~
hawleyal
JAX-RS still has the same problem with nesting and redundancy, doesn't fit the
word "micro" or draw parallels with Sinatra.

~~~
pron
To quote another commenter, here's JAX-RS code:

    
    
      @Path("/hello")
      public class HelloWorld {
        @GET
        public String get() {
          return "Hello World";
        }
      }
    

Seems very Sinatra-like to me.

~~~
hawleyal
You don't see all the redundancies in that code?

I see the term "get" twice. The class name is redundant with the resource
path. I suppose not a huge problem because many MVC frameworks require
classes, but not even close to Sinatra.

Sinatra:

    
    
      get '/hi' do
        "Hello World!"
      end

~~~
meddlepal
You're counting required language keywords towards what makes a micro-
framework? That's bullshit. You're never going to get away from some of the
keywords in Java, nor does that make JAX-RS less 'micro'

Here is an example in Groovy using JAX-RS:

    
    
      @Path("/hello")
      class HelloWorld {
    
        @GET 
        def sayHello() {
          "Hello, world!"  
        }
      }
    

Almost as clean. The braces and parens make it a bit uglier; but those are
just part of the language.

~~~
towelrod
The point is that you shouldn't have to configure things like @Path because
they can be inferred from the class name. Why not:

    
    
      class Hello {
        def get() {
          "Hello, world!"
        }
      }
    

I would prefer to see this and then let someone have a routing config
somewhere else if they want to move the /hello endpoint.

~~~
meddlepal
Sounds like a preferential thing then; I prefer to keep everything together.

I've never liked the separate routing config approach. Play Framework uses(d?)
it in the 1.x branch and I always found it annoying.

Similarly old-world Servlets were done that way too. You'd put the routing
information in an XML file and the container would read it at start up.

------
hawleyal
Somehow having that much nesting and redundancy doesn't fit the word "micro"
or draw parallels with Sinatra.

Sinatra:

    
    
      get '/hi' do
        "Hello World!"
      end
    

Spark:

    
    
      public class HelloWorld {
         public static void main(String[] args) {      
            get(new Route("/hello") {
               @Override
               public Object handle(Request request, Response response) {
                  return "Hello World!";
               }
            });
         }
      }

~~~
tga
All the nesting and redundancy come from Java itself. Verbose as it may be,
after you use any language for a while you will see right through the syntax
and it will not add (much) cognitive load to your work.

I think the value here is in having a micro _framework_ that allows you to put
together a web app without having to juggle a horribly complex abstraction
hierarchy for even the simplest of tasks.

~~~
hawleyal
Syntax is what makes the framework micro.

Following your point about the cruft being from the language, Spring MVC is as
"micro" as Spark. In fact, it is shorter.

Spring MVC:

    
    
      @Controller
      public class HelloController {
        @RequestMapping(value = "/hello", method = RequestMethod.GET)
        public @ResponseBody String hello() {
          return "Hello World!";
        }
      }
      

Spark:

    
    
      public class HelloWorld {
         public static void main(String[] args) {      
            get(new Route("/hello") {
               @Override
               public Object handle(Request request, Response response) {
                  return "Hello World!";
               }
            });
         }
      }

~~~
tga
You don't call a framework "micro" based on the amount of code it takes to
achieve certain tasks. You call it "micro" because it's small enough that you
can learn and truly master in a short time (and you get that by cutting out as
many non-essential features as possible).

Therefore,

Micro:
[http://www.sparkjava.com/readme.html](http://www.sparkjava.com/readme.html)

Not micro: [http://docs.spring.io/spring/docs/3.2.x/spring-framework-
ref...](http://docs.spring.io/spring/docs/3.2.x/spring-framework-
reference/html/)

The downside when using a micro framework is that you always walk a fine line
between simplicity and code reuse. Because of this, as the application grows
you do end up writing _more_ code than with a complex framework because you
slowly start reinventing the wheel -- this is the old argument you hear over
and over (Flask vs Django, Sinatra vs Rails, BackboneJS vs AngularJS, etc.)

------
trailfox
Speaking of Sinatra-inspired web frameworks on the JVM have a look at
Scalatra:

[http://scalatra.org/](http://scalatra.org/)

[https://github.com/scalatra/scalatra](https://github.com/scalatra/scalatra)

~~~
k__
I liked most of it. But when it came to this atmosphere stuff, it was vietnam
all over again!

What's wrong with those Scala developers?

They could make beautiful frameworks and APIs, always start to create crazy
method names.

> "org.scalatra" %% "scalatra-atmosphere" % "2.2.1",

> send(("author" -> "system") ~ ("message" -> "Only json is allowed") ~
> ("time" -> (new Date().getTime.toString )))

What's wrong with them?!

~~~
dscrd
Same symptom is shown in Haskell circles. I suspect it might be due to the
enthusiasts of these languages often being mathematicians. And mathematicians
love crazy sigils, as we know.

~~~
k__
probably :\

And this is rather sad.

You got a language which allows you to write nearly litteral code and still
build stuff only mathematicans can understand.

------
6ren
I think it's simpler to tribute Sinatra in Java by annotating methods:

    
    
      @get('/hi')
      String myMethod() {
        return "Hello World!";
      }
    

I made a prototype of this (including extracting arguments Sinatra-style,
which I think is its coolest bit), and didn't encounter any serious problems
with this approach.

~~~
jebblue
I like reducing the number of annotations which is one reason I like the
SparkJava approach.

~~~
6ren
Java 8 lambdas might shorten their approach too.

~~~
jebblue
I've reviewed Lambdas and still don't think the syntax is clearer to me than
just using an Anonymous Class. Either way, less configuration and less
annotations, whatever lets me do that I could buy into as long as the
debugging isn't a mess.

------
drawkbox
Definitely something that was needed, microframeworks are great. Restlet I
used long ago but still very Java enterprisey. Play! is like Java's
Django/Rails and now Spark is the Sinatra, simple and minimal. Scalatra
mentioned here looks great as well, all these wonderful minimal Java toys.

------
habosa
This is fantastic. I know a lot of programming languages and I love them all
for different reasons, but I think I am most productive and most likely to
produce error-free programs in Java. All the verbosity that people hate is a
feature to me, I know exactly what my program is doing.

However, I have done 95% of my web development in Ruby due to the Sinatra and
Rails frameworks. The developer experience is too good to ignore. I'm hoping
this can replace my Sinatra use case ... I don't think the magic of Rails
could ever be replicated in Java.

------
stevvooe
Where does this stand against dropwizard?

~~~
mbell
Personally, I would use dropwizard. Spark's key point seems to be avoiding
annotation based constructs.

Compare (Spark):

    
    
      public class HelloWorld {
         public static void main(String[] args) {      
            get(new Route("/hello") {
               @Override
               public Object handle(Request request, Response response) {
                  return "Hello World!";
               }
            });
         }
      } 
    

to (JAX-RS, which dropwizard uses)

    
    
      @Path("/hello")
      public class HelloWorld {
        @GET
        public String get() {
          return "Hello World";
        }
      }

~~~
newobj
Annotations are great until you want to do ANYTHING dynamic. "It's a trap!"
Everytime without fail I want to do this kind of thing I end up ripping it all
out later when I need more flexibility.

If Dropwizard lets me fall back to non-annotations, then awesome.

Really, five minutes ago I didn't know either of these projects existed, so
right now I'm feeling a little giddy either way you slice it!

~~~
mbell
I don't know what you mean by dynamic but dropwizard is just a selection of
other libraries wired together into a framework with supporting code (config,
etc) which is built for high performance HTTP services serving JSON, but it
can do HTML rendering. The above code is compliant with any JAX-RS
implementation, JAX-RS is probably the most well done Java spec I've ever
worked with which isn't saying much, but it doesn't suck.

~~~
penrod
One example would be that with Spark you could procedurally create and
register multiple Route instances. That is not an option with an annotation-
based API that requires you to have a distinct annotated class per route.

More abstractly, one of the characteristics of object-oriented design is the
use of polymorphic objects. APIs which require you to define monomorphic
annotated classes violate this and lose generality as a result. They are
effectively class-oriented or method-oriented rather than true OO.

~~~
meddlepal
Why would you want that feature? Also I'm pretty sure nothing about jaxrs
annotations prevents such a thing from being possible but the servlet
container may get in your way of doing it easily.

~~~
penrod
Why would you want to procedurally generate routes or verbs? I dunno, perhaps
there might be a use case where one would want to define them in configuration
or a database. But being able to do something like this is not a "feature,"
it's just the inherent flexibility of expressing semantics in _code_.

Why would you want an API that breaks the flexibility of code by forcing it to
be glorified XML?

------
film42
This looks really cool, I can't wait to hack around with this!

Question for the community: I don't have enough experience to know how this
stacks up against other servers out there. Also, how do the people HN enjoy
using java as a webserver (lang-wise, scaling-wise, etc)?

Any feedback would be much appreciated!!

~~~
mugenx86
I've never enjoyed using Java.

If you have time look at Scala (Scalatra/Play Framework) or Clojure (Ring).
You can reduce the size of your codebase dramatically.

~~~
codenut
Ive enjoyed writing code in scala, not until I compile it. It takes a long to
compile. I agree with you, java is not enjoyable but we cannot deny the fact
it still gets the job done.

~~~
hrjet
That used to be true earlier, but the compile times in Scala are pretty good
these days. Also I hear that a faster compiler is expected with the 2.11
release. Incremental compilation in Eclipse is already real-time.

But in general, IMO, compile times shouldn't be a major factor in choosing a
language; expressiveness and run-times are more important.

~~~
programminggeek
That's only partially true. Compile times are absolutely a factor in
development time for the same reason that how long your test suite takes to
run is a factor. A faster feedback loop can shorten dev cycles. If nothing
else, it's more fun to have faster compiles.

This is one reason Go is so appealing to many people. The compile times make
it "feel" like ruby or python or php in terms of "hit refresh and the change
is there" style of development. That is a huge difference from, hit save and
wait a minute for my java project to compile, and push out to tomcat a minute
later. Even with JRebel the best I've seen is a 2-5 second page change refresh
cycle in Scala and a minimum 5 second test suite reload time using SBT.

Scala is a beautiful language, but compared to Go, it's a very slow dev cycle.

------
ShabbyDoo
I had looked at Spark a couple of weeks ago. I'm looking for a lightweight
service-y sort of framework which just happens to have a good HTTP service
available out-of-the-box. My application does back-end processing and
coordinates a bunch of data feeds, thick-client HTTP requests, background
processing, etc. all together. Spark was too web-centric (not a bad thing,
just not what I need). OSGi was an attempt to be what I want, but its
requirement of classpath isolation (a good idea conceptually) is onerous in
practice. Right now, I'm using a homespun amalgam of Grizzly, Guice, and
java.util.concurrent (for thread pooling), and other stuff. I really didn't
want to build my own container. I'm intrigued by Apache Karaf, but OSGi is a
huge pill to swallow (If you haven't debugged OSGi classloading issues, you'd
be in for a treat).

In a nutshell, I want a service lifecycle container which allows me to write
small, lightweight, modular services which depend on each other. The container
should provide for cross-cutting concerns like monitoring, management,
configuration, logging, auditability (I have concrete definitions for these
things -- they're not just abstract biz-speak to me). HTTP should be an out-
of-the-box, optional module. A service which exposes another service via a
RESTful interface and depends upon the HTTP service should be another. For my
application, services which listen to multicast data streams are just as
important interfaces to the world as JSON-over-HTTP-via-REST. I want to write
the HelloWorld method body and be able to do stuff like: expose it via a
RESTful interface, invoke it every N seconds, inject an interface exposing the
HelloWorld contract into other services, etc. When I want to know how my
HelloWorld service is performing, there's a pre-built web interface which
provides New Relic-esque views. I'd like to capture audit trails of the
transactional flows through my services from an origination point (HTTP call,
scheduled job, etc.) so I can translate failures, poor performance, usage
rates, etc. into meaningful information (I wrote a poor man's version of this
myself, and it's been quite useful).

Does anything like this exist? I sure can't find it. Modern JBoss (now
Wildfly) might actually be closer to my requirements than I think. Perhaps I
should look at the work they're doing on Version 8.

~~~
pron
Using Grizzly/Netty as the core comm component seems like a good idea. Jersey
integrates will with Grizzly, I think.

Dropwizard packages together Jersey on top of Jetty with good monitoring, but
doesn't take care of other stuff like multicast. Nothing prevents you from
adding Netty/Grizzly into the mix, though.

Actually, the modularity, composability and cross-cutting concerns you mention
suggest Spring – not lightweight by any means, but neither are your
requirements :)

I think you can even use Jersey with Spring:
[http://www.infoq.com/articles/springmvc_jsx-
rs](http://www.infoq.com/articles/springmvc_jsx-rs)

------
msgilligan
Ratpack Framework is a Sinatra-inspired framework for the JVM worth noting:
[http://www.ratpack-framework.org](http://www.ratpack-framework.org)

Groovy:

    
    
      ratpack {
        handlers {
          get('hello') {
            response.send "Hello world!"
          }
        }
      }
    

It can also be used (with somewhat less brevity) in good, old-fashioned Java.

An 0.9.0 release is expected in a few weeks and the project is undergoing
rapid (and sometimes API-changing) development, but it looks very promising.

------
nahname
Have people dropped the 'com' from java projects now? Not arguing in favor,
the whole thing is ridiculous to me (src/main/com/actual_files). Just curious.

~~~
brazzy
It would actually be src/main/com/organization/project/actual_files

And there are good reasons for that - naming packages after internet domains
prevents namespace clashes and is consistently used by most Java projects.

It's actually projects that diverge from this convention that stand out like a
sore thumb, and many that did have adopted it eventually, like JUnit.

------
scorchin
There's also webbit-rest: [https://github.com/webbit/webbit-
rest](https://github.com/webbit/webbit-rest)

------
Zolomon
I wrote a semi-realtime implementation of the planning poker estimation
technique at [1] using Spark and some template engine I found.

This was for a course in software project management with some time
restraints, so only focused on getting it done.

[1]
[https://github.com/Zolomon/PlanningPoker](https://github.com/Zolomon/PlanningPoker)

------
bhauer
For what it's worth, Spark performs quite well in terms of request routing
when compared to other JVM frameworks of various sizes [1].

[1]
[http://www.techempower.com/benchmarks/#section=data-r6&hw=ec...](http://www.techempower.com/benchmarks/#section=data-r6&hw=ec2&test=json&l=6g4)

------
kitd
Very nice! Had a look at this a year or so ago and it would be a great base
for mocking up backends IMHO.

In a similar vein is Google SiteBricks:
[http://sitebricks.org/#home](http://sitebricks.org/#home)

Slightly heavier weight but with more features (templating, annotations, etc).
Depends on Guice.

------
chotachetan
It is a nice one. I use Jelastic(www.jelastic.com) for my startup. What if we
can have the same functionality there integrated. But this is needed at least
the microframeworks are nice. Thinking that the same kind of thing can be also
achieved with he framework integration in Jelastic.

------
Oculus
Finally a web framework I can use. All the Java web frameworks I tried to use
are way too enterprise-y.

~~~
edwinnathaniel
You should expand your horizon once in a while. JAX-RS has ben her for a
while. Ditto with Spring MVC.

------
Shank
It really bugs me that they decided to clone the Sinatra README page, keeping
most of the docs on one giant list instead of a more traditional multi-page
doc approach. See here:
[http://www.sparkjava.com/readme.html](http://www.sparkjava.com/readme.html)

In addition, some of their docs link to a Google Code page, which keeps some
examples on its index too: [https://code.google.com/p/spark-
java/](https://code.google.com/p/spark-java/)

Lastly, it appears they're using GitHub for actual code, and, while they have
a Github wiki created, it has no information.

I wish I could stress just how important it is to have all of the docs in one
centralized location. Somewhere along the line, one of the five places they
have examples will get out of date, and it'll be difficult to play spot the
differences when it's replicated everywhere.

------
matt__ring
I love it! Just whipped up a couple of toy web services in 15 mins using
Spark. They will be part of a technical interview coding task.

True, Spark may not be better/more concise than JAX-RS, but fun to try anyway.

------
f4stjack
Okay. I am holding the idiot ball here: How can we deploy an app developed
with spark? What are our options? Heroku? AWS? I haven't seen anything
regarding to deployment in the documentation.

~~~
msluyter
Well, there's a howto on running on tomcat:

[http://www.sparkjava.com/readme.html#title17](http://www.sparkjava.com/readme.html#title17)

As for Heroku, I found this:

[https://gist.github.com/Fitzsimmons/2490382](https://gist.github.com/Fitzsimmons/2490382)

Generally, for a lot of apps the embedded Jetty webserver might be sufficient.

------
rubiquity
I feel like Keurig would be a no brainer as a name for a Java micro Web
framework.

------
waffenklang
would love to see such a mf for c/c++...

~~~
papaf
[https://github.com/d5/node.native](https://github.com/d5/node.native)

~~~
waffenklang
not exactly a microframework, but an interesting approach to build a basis for
it, like rack for sinatra.

