March 7, 2017

Ratpacked: Type Check And Static Compilation For Groovy DSL

One of the very nice features of Ratpack is the Groovy DSL to define our application. We get a nice DSL to set up the registry, to define handlers and more. Because of clever use of the @DelegateTo annotation we get good code completion in our IDE. We can also add static compilation of our Groovy DSL when we start our Ratpack application. With static compilation the script is type checked at compile time so we get earlier feedback on possible errors in the script. To configure static compilation we must invoke the app method of the Groovy.Script class with the argument true.

We start with a Groovy DSL for an application that serves recipes. Notice the Closure arguments are all typed, so with type checking there are no errors.

// File: src/ratpack/ratpack.groovy
import mrhaki.ratpack.Recipe
import mrhaki.ratpack.RecipeRenderer
import mrhaki.ratpack.RecipeRepository
import mrhaki.ratpack.RecipeRequest
import mrhaki.ratpack.RecipesList

import static ratpack.groovy.Groovy.ratpack

ratpack {
    bindings {
        add new RecipeRenderer()
        add RecipeRepository, new RecipesList()
    }

    handlers {
        post('recipe') { RecipeRepository recipeRepository ->
            parse(RecipeRequest)
                    .flatMap { RecipeRequest recipeRequest -> 
                        recipeRepository.findRecipeByName(recipeRequest.name) 
                    }
                    .then { Optional<Recipe> optionalRecipe -> 
                        render(optionalRecipe) 
                    }
        }
    }
}

Next we create a class with a main method that will be the starting point of our application. We need to run this class to start our Ratpack application. The example class is a Java class, but could also be written with Groovy:

// File: src/main/java/mrhaki/sample/GroovyCompileStaticRatpackMain.java
package mrhaki.ratpack;

import ratpack.groovy.Groovy;
import ratpack.server.RatpackServer;

import java.util.Optional;

public class GroovyCompileStaticRatpackMain {
    
    public static void main(String[] args) throws Exception {
        RatpackServer.start(Groovy.Script.app(true /* compileStatic */));
    }
}

When we use the Gradle Ratpack plugin we use this class as the main class:

// File: build.gradle
...
mainClassName = 'mrhaki.ratpack.GroovyCompileStaticRatpackMain'
...

Now we can still use the run task to start our Ratpack application.

Written with Ratpack 1.4.5.