Ratpacked: Register Renderer For A List Of Objects
When we use the render
method in our Ratpack application then Ratpack will use the type of the object we want to render to find an appropriate renderer. Some renderers are built-in, like a Promise
or CharSequence
renderer. We can write our own renderers by implementing the ratpack.render.Renderer
interface. Next we must register our renderer in the Ratpack registry.
In our example application we have a very simple User
class:
// File: src/main/groovy/com/mrhaki/ratpack/User.groovy
package com.mrhaki.ratpack
class User {
String username
}
We define a renderer for a list of User
objects:
// File: src/main/groovy/com/mrhaki/ratpack/UserListRenderer.grooovy
package com.mrhaki.ratpack
import com.google.inject.util.Types
import ratpack.handling.ByContentSpec
import ratpack.handling.Context
import ratpack.jackson.Jackson
import ratpack.render.Renderer
import static ratpack.groovy.Groovy.markupBuilder
class UserListRenderer implements Renderer> {
/**
* Define that this renderer is used for List instance
* with User instances.
*
* @return Type of List */
@Override
Class> getType() {
Types.listOf(User).rawType
}
@Override
void render(Context context, List userList) throws Exception {
// We return different responses based on the
// requested content type.
context.byContent { ByContentSpec spec ->
spec
// Render JSON response.
.json {
context.render(Jackson.json(userList))
}
// Render XML response
.xml {
// Use markupBuilder method to create XML content.
context.render(markupBuilder('application/xml', 'UTF-8') {
users {
userList.each { singleUser ->
user {
username(singleUser.username)
}
}
}
})
}
}
}
}
Now we use the UserListRenderer
in the configuration of our Ratpack application:
// File: src/ratpack/ratpack.groovy
import com.mrhaki.ratpack.UserListRenderer
import static ratpack.groovy.Groovy.ratpack
ratpack {
bindings {
// Add renderer for a list of users
// to the registry.
bind(UserListRenderer)
// Create two sample users.
bindInstance(['mrhaki', 'hubert'].collect { String name ->
new User(username: name)
})
}
handlers {
get('users') { List users ->
// Render the list of users
// fetched from the registry.
// Ratpack will use the
// UserListRenderer we have added
// to the registry.
render(users)
}
}
}
When we invoke the URL http://localhost:5050/users
for both JSON and XML content we get the following results:
$ http localhost:5050/users Accept:application/json
connection: keep-alive
content-encoding: gzip
content-type: application/json
transfer-encoding: chunked
[
{
"username": "mrhaki"
},
{
"username": "hubert"
}
]
$ http localhost:5050/users Accept:application/xml
connection: keep-alive
content-encoding: gzip
content-type: application/xml
transfer-encoding: chunked
mrhaki
hubert
$
Written with Ratpack 1.1.1.