a port of Rack to Java
Clone or download
Pull request Compare This branch is 46 commits ahead, 31 commits behind florinpatrascu:master.
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.settings
docs/api
src/main/java/org/rack4java
.classpath
.gitignore
.project
LICENSE.txt
README.md
build.xml

README.md

Rack 4 Java

In the world of dynamic language web development it is common for the interface between server, web framework, and application components to be simple and standard. Most have settled on a particular style:

and more, all have a lot in common.

An request is represented as an associative array ("Map", "Hash", "Dictionary" etc.) populated with a standard set of named items, but able to contain others. A response is represented as a triplet of [response code, headers, body]

This is extremely simple compared with the Java Servlet API usually considered as the standard way to interface web applications with web servers. This simplicty has many advantages:

  • it's much easier to implement, so lots of people can support it in their servers
  • it's much easier to work with, so both frameworks and raw applications can be simpler
  • it's much easier to mock/stub, so framework and application code is easier to test
  • it's much easier to use the "decorator" pattern, so applications can be much more modular

The last point is particularly important. Ruby Rack has a vibrant ecosystem of "middleware" for all sorts of common tasks and processes, making application developmentmuch easier by simply combining and re-arranging pre-built blocks with no change to application code at all.

I want these benefits for my Java development!

Rack 4 Java is An ultra-lightweight Rack port for Java

The key goals of this project are:

  1. To produce a tiny Rack layer for Java, with no external dependencies
  2. To ensure that it works acceptably for all types of HTTP request and response
  3. To be as compatible as possible with the spirit of the original Rack specification
  4. To be as performant as possible within the constraints of the essential API

All of these goals contribute to the overall aim of a very thin, agnostic layer to connect wildly different types of web servers, applications and third-party APIs. In particular this means no dependency on the Servlet API, to encourage and unify non-servlet servers. A simpler web API is also vital to bring the joy of Test-Driven development to all levels of java web software.

That's not to say that a servlet server can't make use of Rack4Java, it just needs a Servlet which passes through requests and responses from the complex and largely untestable Servlet API to the much simpler Rack API. I have added Some example code to do this to GitHub.

How It Works

A Rack4Java application can be very simple. For example:

import org.rack4java.Context;
import org.rack4java.Rack;
import org.rack4java.RackResponse;

public class HelloWorld implements Rack {
    public Context<String> call(Context<String> input) {
        return new RackResponse(200)
    	    .withHeader("Content-Type", "text/plain")
    	    .withBody("Hello World");
    }
}

When plugged in to a Rack4Java friendly server, this will respond with the usual greeting to any request.

Notes:

  • Java is strongly typed and does not (yet?) have a sensible or concise literal syntax for Arrays and Maps, so the code looks a bit different to the Ruby version. I hope it's equivalenty simple, readable and usable.
  • Context is just a very simple interface, roughly equivalent to Map<String,?>
  • RackResponse is just a MapContext with a bunch of helper methods. You don't have to use it and can return any Context which has the appropriate entries.

Associated Projects

Building

To build Rack4Java you will need a java compiler and Ant.

Checkout the Rack4Java code and cd to that directory.

git clone git@github.com:rack4java/rack4java.git
cd rack4java
ant

The generated jar should be located here: dist/rack4java-*.jar

TODO

  • add tests for different cases (empty data, multiple headers, etc..)
  • add javadoc and generate doc pages
  • publish to a maven repo somewhere

DONE

  • Strip out servlet dependencies from JRack and examples
  • improve test coverage of existing examples
  • support easier header syntax
  • Remove all dependencies
  • add tests for binary data