In Ratpack we can use the byContent method on the Context object to send different responses based on the requested MIME type from the client. There is already support for application/json, application/xml, text/plain and text/html MIME types with corresponding methods of the ByContentSpec object that is passed as argument to the byContent method. We can match on a custom MIME type with the method type and specify the MIME type. If the type matches we can create a response.

In the following example application we have a custom renderer for a User object:

// File: src/main/groovy/com/mrhaki/ratpack/UserRenderer.groovy
package com.mrhaki.ratpack

import ratpack.handling.ByContentSpec
import ratpack.handling.Context
import ratpack.jackson.Jackson
import ratpack.render.RendererSupport

import static ratpack.groovy.Groovy.markupBuilder

class UserRenderer extends RendererSupport {

    @Override
    void render(Context context, User user) throws Exception {
        context.byContent { ByContentSpec spec ->
            spec
                .type('application/vnd.com.mrhaki.user+json;v=1') {
                    context.render(Jackson.json(user))
                }
                .type('application/vnd.com.mrhaki.user+xml;v=1') {
                    context.render(markupBuilder('application/xml', 'UTF-8') {
                        delegate.user {
                            username(user.username)
                        }
                    })
                }
        }
    }

} 

Next we use it in our Ratpack definition:

import com.mrhaki.ratpack.User
import com.mrhaki.ratpack.UserRenderer

import static ratpack.groovy.Groovy.ratpack

ratpack {
    bindings {
        // Register renderer for User objects.
        bind(UserRenderer)

        // Create two sample users.
        bindInstance(\['mrhaki', 'hubert'\].collect { String name ->
            new User(username: name)
        })
    }

    handlers {
        get('user/:username') { List users ->
            // Get value for username token.
            final String username = pathTokens.username

            // Find user in list of users.
            final User user = users.find { User user ->
                user.username == username
            }

            // Render user object.
            render(user)
        }
    }
} 

When we make a request with different accept MIME types we see different results:

$ http localhost:5050/user/mrhaki Accept:application/vnd.com.mrhaki.user+xml;v=1
connection: keep-alive
content-encoding: gzip
content-type: application/xml
transfer-encoding: chunked

 mrhaki 

$ http localhost:5050/user/mrhaki Accept:application/vnd.com.mrhaki.user+json;v=1
connection: keep-alive
content-encoding: gzip
content-type: application/vnd.com.mrhaki.user+json;v=1
transfer-encoding: chunked

{
    "username": "mrhaki"
}

$

Written with Ratpack 1.1.1.

Original post

shadow-left