Many times when a developer hears the word Java, it conjures up images of clunky, "enterprise" applications with layers of abstractions, SimpleBeanFactoryAwareAspectInstanceFactories, and loads of unnecessary boilerplate code.

To a point, a lot of this is well deserved. Java as a language requires a good deal of ceremony and the frameworks available, though incredibily powerful, haven't always been the easiest to use. However, it doesn't have to be that way. Through the use of some newer frameworks, some pretty basic design patterns and aided by Java 8's new lambda expressions, we can get a minimal Java web application up and running quite quickly. The best part is, we can keep the sound design methods that help applications stay maintainable, while shedding that enterprisey baggage.

The Spark Framework (not to be confused with Apache Spark) is a Sinatra inspired framework for creating web applications. Like Sinatra, it uses a simple routing syntax and contains the basic facilities needed for most HTTP APIs.

The basic "hello world" from the home page looks like this:

import static spark . Spark .*; public class HelloWorld { public static void main ( String [] args ) { get ( "/hello" , ( req , res ) -> "Hello World" ); } }

Here's Sinatra's:

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

As you can see, it's not a huge difference, with the exception of needing to define a class and main method. Contrast that with the Spring Boot version:

import org.springframework.boot.* ; import org.springframework.boot.autoconfigure.* ; import org.springframework.stereotype.* ; import org.springframework.web.bind.annotation.* ; @Controller @EnableAutoConfiguration public class SampleController { @RequestMapping ( "/" ) @ResponseBody String home () { return "Hello World!" ; } public static void main ( String [] args ) throws Exception { SpringApplication . run ( SampleController . class , args ); } }

The Spring boot version is much smaller than your usual Spring application, but there is still a lot of unnecessary noise due to all the annotations. One of aspects of Spark that I like is the simple routing DSL. Annotations can be an incredibily powerful mechanism for declarative programming, but I find them to be a bit overused in Spring.

Spark is obviously no where near as full featured as Spring MVC, but it does offer everything you would need for the vast majority of web applications. If you are jumping on the microservices train, it might be just the thing for a smaller, lightweight service. However, it doesn't have to be just for small applications. With a little bit of design and best practices, applications of any size could benefit from its simpler design.

Dependency Injection

An application of any decent size requires some organization and since we want to use good patterns in our applications, we'll likely want to use dependency injection to increase encapsulation and testability. However, if we aren't using Spring, what will we use as a container? Though it still has it, Spring's XML configuration mechanism has been superseded by its Java based configuration, which allows a developer to leverage their IDE without the use of plugins and provides type safety. It's also not, you know... XML. Interestingly, if you strip off the annotations from the configuration, it reveals the truth about DI: at its core, it's just a pattern and you don't really need a container. Just use constructor injection and a simple class with static fields as the container.

Example Application

I've created a small example application in Spark that shows how to do this:

https://github.com/cantinac/spark-example.

To run it, just make sure you have Maven and the Java 8 SDK and run the following from the example root directory:

mvn compile exec:java

Now you can check out the API in your browser:

http://localhost:4567/books

http://localhost:4567/books?title=Domain

The example application is a very simple API to search for books. It's only components are a book repository to store and search the books, and a ResponseTransformer to transform the result into JSON. Here's how I've wired those up so they can be accessed in the routes:

public class Application { private static ObjectMapper jacksonMapper () { ObjectMapper mapper = new ObjectMapper (); mapper . registerModule ( new SimpleModule ( "Java 8 Streams" , unknownVersion (), asList ( StreamSerializer . INSTANCE ) )); return mapper ; } public static final JsonTransformer jsonTransformer = new JsonTransformer ( jacksonMapper () public static final BookRepository bookRepository = new InMemoryBookRepository ( Arrays . asList ( new Book ( "Domain Driven Design" , "Eric Evans" ), new Book ( "Implementing Domain Driven Design" , "Vaugn Vernon" ), new Book ( "Functional Programming in Scala" , "Paul Chiusano and Rúnar Bjarnason" ) )); }

I wanted to use Java 8 Streams so I added in a Jackson module for converting them to JSON. That's handy because it shows how the ObjectMapper is injected into the JsonTransformer.

In the controller, we can just statically import those for convenient access:

import static co . cantina . example . Application .*; import static spark . Spark .*; public class Main { public static void main ( String [] args ) { get ( "/books" , "application/json" , ( req , res ) -> { String title = req . queryParams ( "title" ); if ( title == null ) { return bookRepository . findAllBooks (); } else { return bookRepository . findBooksByTitle ( title ); } }, jsonTransformer ); } }

Obviously this is a trivial example, but you can easily extrapolate how to build out the application. Consider adding a service layer to keep the glue code out of the HTTP layer and to provide an API for other interfaces other than just HTTP.

Smaller, more specialized frameworks such as Spark can often be an adequate replacement for much larger and more complex frameworks like Spring MVC. With Java 8's lambda feature breathing a bit of new life into the language, I think we'll see a lot more minimalist frameworks and libraries which we can mix and match rather than always reaching for the big hammer.