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<List<User>> {
/**
* Define that this renderer is used for List instance
* with User instances.
*
* @return Type of List<User>
*/
@Override
Class<List<User>> getType() {
Types.listOf(User).rawType
}
@Override
void render(Context context, List<User> 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<User> 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
HTTP/1.1 200 OK
connection: keep-alive
content-encoding: gzip
content-type: application/json
transfer-encoding: chunked
[
{
"username": "mrhaki"
},
{
"username": "hubert"
}
]
$ http localhost:5050/users Accept:application/xml
HTTP/1.1 200 OK
connection: keep-alive
content-encoding: gzip
content-type: application/xml
transfer-encoding: chunked
<users>
<user>
<username>mrhaki</username>
</user>
<user>
<username>hubert</username>
</user>
</users>
$
Written with Ratpack 1.1.1.