Ratpack uses renderers to render output. We can create our own renderer by implementing the Renderer
interface. The renderer class needs to implement a render
method that has the object we want to render as argument. Alternatively we can add the logic to render a object to the class definition of that object. So instead of having a separate renderer class for a class, we add the render logic to the class itself. To achieve this we must implement the Renderable
interface for our class. Ratpack provides a RenderableRenderer
in the registry that knows how to render classes that implement the Renderable
interface.
In the following example we have a Recipe
class that implements the Renderable
interface:
// File: src/main/java/mrhaki/ratpack/Recipe.java package mrhaki.ratpack; import ratpack.handling.Context; import ratpack.render.Renderable; import static ratpack.jackson.Jackson.json; public class Recipe implements Renderable { private final String name; public Recipe(final String name) { this.name = name; } public String getName() { return name; } /** * Render object as JSON. * * @param context Ratpack context. */ @Override public void render(final Context context) throws Exception { context.byContent(content -> content .plainText(() -> context.render(this.toString())) .json(() -> context.render(json(this)))); } public String toString() { return String.format("Recipe::name=%s", this.name); } }
Let's write a specification to test how the Recipe
is rendered:
// File: src/test/groovy/mrhaki/ratpack/RecipeRenderableSpec.groovy package mrhaki.ratpack import groovy.json.JsonSlurper import ratpack.test.embed.EmbeddedApp import spock.lang.Specification class RecipeRenderableSpec extends Specification { def app = EmbeddedApp.fromHandler { ctx -> ctx.render(new Recipe('macaroni')) } def httpClient = app.httpClient void 'render Recipe as plain text'() { when: def response = httpClient.requestSpec { request -> request.headers.set 'Accept', 'text/plain' }.get() then: response.statusCode == 200 and: response.body.text == 'Recipe::name=macaroni' } void 'render Recipe as JSON'() { when: def response = httpClient.requestSpec { request -> request.headers.set 'Accept', 'application/json' }.get() then: response.statusCode == 200 and: def recipe = new JsonSlurper().parseText(response.body.text) recipe.name == 'macaroni' } }
Written with Ratpack 1.4.5.