Ratpacked: Combine Groovy DSL With RatpackServer Java Configuration
We have several options to define a Ratpack application.
We can use a Java syntax to set up the bindings and handlers.
Or we can use the very nice Groovy DSL.
It turns out we can use both together as well.
For example we can define the handlers with the Groovy DSL and the rest of the application definition is written in Java.
To combine both we start with the Java configuration and use the bindings
and handlers
method of the Groovy.Script
class to inject the files with the Groovy DSL.
We start with a sample application where we use Java configuration to set up our Ratpack application:
package mrhaki.ratpack;
import ratpack.func.Action;
import ratpack.handling.Chain;
import ratpack.handling.Handler;
import ratpack.registry.RegistrySpec;
import ratpack.server.RatpackServer;
import java.util.Optional;
public class Application {
public static void main(String\[\] args) throws Exception {
new Application().startServer();
}
void startServer() throws Exception {
RatpackServer.start(server -> server
.registryOf(registry())
.handlers(chain()));
}
private Action registry() {
return registry -> registry
.add(new RecipeRenderer())
.add(RecipeRepository.class, new RecipesList());
}
private Action chain() {
return chain -> chain.post("recipe", recipeHandler());
}
private Handler recipeHandler() {
return ctx -> ctx
.parse(RecipeRequest.class)
.flatMap(recipeRequest -> ctx
.get(RecipeRepository.class)
.findRecipeByName(recipeRequest.getName()))
.then((Optional optionalRecipe) -> ctx.render(optionalRecipe));
}
}
We can use the Groovy DSL for the bindings and handlers definitions and use them in our Java class with the Groovy.Script
class.
First we create the files bindings.groovy
and handlers.groovy
in the directory src/main/resources
so they will be in the class path of the Java application.
We can use the Groovy DSL syntax in the files:
import mrhaki.ratpack.RecipeRenderer
import mrhaki.ratpack.RecipeRepository
import mrhaki.ratpack.RecipesList
import static ratpack.groovy.Groovy.ratpack
ratpack {
bindings {
add new RecipeRenderer()
add RecipeRepository, new RecipesList()
}
}
import mrhaki.ratpack.Recipe
import mrhaki.ratpack.RecipeRepository
import mrhaki.ratpack.RecipeRequest
import static ratpack.groovy.Groovy.ratpack
ratpack {
handlers {
post('recipe') { RecipeRepository recipeRepository ->
parse(RecipeRequest)
.flatMap { RecipeRequest recipeRequest ->
recipeRepository.findRecipeByName(recipeRequest.name)
}
.then { Optional<Recipe> optionalRecipe ->
render(optionalRecipe)
}
}
}
}
We have our Groovy DSL files with the definitions. To use them in our Java code to define the Ratpack application we must make sure Ratpack can find them.
Therefore we create an empty marker file .ratpack
in src/main/resources
.
With this file in place we can use Ratpack’s findBaseDir
method to set the base directory for finding external files.
It is time to refactor our application:
package mrhaki.ratpack;
import ratpack.func.Action;
import ratpack.groovy.Groovy;
import ratpack.handling.Chain;
import ratpack.handling.Handler;
import ratpack.registry.RegistrySpec;
import ratpack.server.RatpackServer;
import java.util.Optional;
public class Application {
public static void main(String\[\] args) throws Exception {
new Application().startServer();
}
void startServer() throws Exception {
RatpackServer.start(server -> server
// Set base dir with directory that
// contains marker file .ratpack.
.serverConfig(config -> config.findBaseDir())
// Use bindings.groovy with static compilation.
.registry(Groovy.Script.bindings(true))
// Use handlers.groovy with static compilation.
.handler(Groovy.Script.handlers(true)));
}
}
Written with Ratpack 1.4.5.