Layout and Handlers

Learn about Ratpack layout and handlers.

We'll cover the following

Ratpack layout

  • build.gradle: The Gradle build file
  • src - main/java: Where you put general Java classes.
    • main/groovy: Where you put general Groovy classes.
    • main/resources: Where you put static resources, such as Handlebars templates.
    • test/java: Where to put your Java based tests.
    • test/groovy: Where to put your spock Specs and other groovy tests.
    • ratpack: Contains
    • ratpack/public: Any public files like HTML, JavaScript, and CSS
    • ratpack/templates: Holds your Groovy-Markup templates (if you have any).


Handlers are the basic building block for Ratpack. They form something like a pipeline or “Chain of Resposiblity.” Multiple handlers can be called per request, but one must return a response. If none of your handlers are matched, a default handler returns a 404 status code.

File base = new File("/opt/myapp");
RatpackServer.start(server - > server
    .handlers(chain - > chain
        .all(ctx - > {
            ctx.getResponse().getHeaders().add("x-custom", "X");
        .get("foo", ctx - > {
            ctx.render("foo handler");
        .files(ctx - > ctx.dir("public"))
        .get(":key", ctx - > {
            String key = ctx.getPathTokens().get("key");
            ctx.render("{\"key\": \"" + key + "\"}");
  1. Firstly, the base directory must be set using the ServerConfig before files can be served.
  2. Secondly, we define the handlers.

The first handler all() is used for every HTTP request and adds a custom header, x-custom. It then calls so the next matching handler gets called. The next handler that matches a given HTTP request will be used to fulfill the request with a response.

The files handler is used to specify what files should be served. In the above example, we specify that all files in the public directory should be server; this is relative to the baseDir.

The pathTokens map contains all parameters passed in the URL as specified in the matching path pattern (as in :key) by prefixing the colon (:) to a variable name you specify. In the above example, we simply return JSON with the key given in the URL.

You can define a handler using a method corresponding to any one of the HTTP methods:

  • get
  • post
  • put
  • delete
  • patch
  • options

To accept multiple methods on the same path, you should use the path handler and byMethod with each method handler inside it. For example:

chain.path("foo", c - >
c.byMethod(spec - > { - > ctx.render("post foo"))
    .put(ctx - > ctx.render("put foo"))
    .delete(ctx - > ctx.render("delete foo"));

Get hands-on with 1200+ tech skills courses.