Basics of Ratpack Handlers

Roberto Guerra

 5 min read

Ratpack is a "simple, capable, toolkit for creating high performance applications" on the JVM. It was originally inspired by Sinatra but it has taken a life of its own with very interesting concepts. It is virtually a treasure cove of neat tricks with Groovy and its @CompileStatic feature. It has not reached 1.0 yet, and it is under heavy development, with releases the 1st of every month.

Ratpack has always attracted me, and I finally got some time to play with it. The documentation is a work in progress, but the core devs are very helpful and the API seems to be stabilizing. So it seemed like the right time to get my feet wet.

Why I'm excited about Ratpack

I've tried Rails-type frameworks (Grails, Django, Rails, etc) and I seem to be very productive with them, but as the application starts to grow, all those initial 'benefits' seem to become obstacles. They seem to encourage tight coupling and it feels like we are building 'Rails/Grails/Django' apps instead of whatever application we are trying to build.

Ratpack tries to encourage us to build very small, lightweight applications that are not tightly coupled to Ratpack itself. It seems to be just a thin shell that allows us to connect to external resources or expose our system to outside world. Since it doesn't provide all these extra heavyweight 'features' like ORMs, mailers, etc; it allows us to think about our design and not just blindly create objects for our ORM that then drive our business logic.

Setting Up

The easiest way to setup a ratpack project is with Gradle and Lazybones. If you have gvm installed you can easily install them:


And starting a ratpack project is as easy as:


This will create a folder in the current directory with the ratpack-app-name. For more information, you can refer to the official documentation


Handlers are responsible for handling response and request objects. They are stateless & asynchronous by default, although we can block explicitly (to be covered in a later blog post). A simple example looks like this:


This will render "Hello!" when we visit http://localhost:5050/hello.

The handler exposes methods whose names match the HTTP verbs - get, post, delete, put - and each method takes a string as a parameter that defines the unique path. For example, get("books") allows us to do a GET at /books. And post("books") allows us to do a DELETE on /books.

Order Matters

The order of the handlers also matter. Those declared at the top are evaluated first. E.g.:


Ratpack will first check if the route matches "hello", if not, it will proceed to the next handler, until it finds a matching one.


If we want to render json, we need to use the JacksonModule:


We can also use prefix if we want to group all these handlers:


Dynamic Paths

We can create dynamic paths pretty easily by prepending a : to the dynamic parts of the route. Every handler has a `pathTokens attribute that allows us to access the dynamic parts of the url through its name:


Static Assets

If we are using the lazybones template to generate a Ratpack application, we can serve up static assets quite easily. Ratpack provides an assets function that takes a string which represents the directory that we want to serve. This directory has to be inside the src/ratpack folder:


The above snippet will serve everything under src/ratpack/css as static assets. We can also serve more than one folder:


These are the basics of how handlers work in Ratpack. In the next installment we will see how we can render templates.