Ratpack

Ratpacked: Handling Exceptions When Reading Configuration Sources

Posted on by  
Hubert Klein Ikkink

To define configuration sources for our Ratpack application we have several options. We can set default properties, look at environment variables or Java system properties, load JSON or YAML formatted configuration files or implement our own configuration source. When something goes wrong using one of these methods we want to be able to handle that situation. For example if an optional configuration file is not found, we want to inform the user, but the application must still start. The default exception handling will throw the exception and the application is stopped. We want to customise this so we have more flexibility on how to handle exceptions.

We provide the configuration source in the serverConfig configuration block of our Ratpack application. We must add the onError method and provide an error handler implementation before we load any configuration source. This error handler will be passed to each configuration source and is execute when an exception occurs when the configuration source is invoked. The error handler implements the Action interface with the type Throwable. In our implementation we can for example check for the type of Throwable and show a correct status message to the user.

Continue reading →

Ratpacked: Use TestHttpClient For External HTTP Services

Posted on by  
Hubert Klein Ikkink

Ratpack has a very useful class: TestHttpClient. This is a blocking HTTP client that we normally use for testing our Ratpack applications. For example we use MainClassApplicationUnderTest or GroovyRatpackMainApplicationUnderTest in a test and invoke the getHttpClient method to get an instance of TestHttpClient. The class has a lot of useful methods to make HTTP requests with a nice DSL. TestHttpClient is also very useful as a standalone HTTP client in other applications.

Suppose we have a piece of code that needs to access MapQuest Open Platform Web Services to get location details for a given combination of longitude and latitude values. In the constructor we create an instance of the interface ApplicationUnderTest. We then can use the getHttpClient method of ApplicationUnderTest to get a TestHttpClient instance:

Continue reading →

Ratpacked: Stub External HTTP Service

Posted on by  
Hubert Klein Ikkink

Suppose we have a piece of code that uses an external HTTP service. If we write a test for this code we can invoke the real HTTP service each time we execute the tests. But it might be there is a request limit for the service or the service is not always available when we run the test. With Ratpack it is very, very easy to write a HTTP service that mimics the API of the external HTTP service. The Ratpack server is started locally in the context of the test and we can write extensive tests for our code that uses the HTTP service. We achieve this using the Ratpack EmbeddedApp or GroovyEmbeddedApp class. With very little code we configure a server that can be started and respond to HTTP requests.

In our example project we have a class GeocodeService that uses the external service MapQuest Open Platform Web Services. We use the HTTP Requests library to make a HTTP request and transform the response to an object:

Continue reading →

Ratpacked: Include Files In The Ratpack Groovy DSL

Posted on by  
Hubert Klein Ikkink

When we define our Ratpack application using the Groovy DSL in a file ratpack.groovy, we can split up the definition in multiple files. With the include method inside the ratpack configuration closure we can use the file name of the file we want to include. The file that we include also contains a ratpack configuration closure. We can use the same bindings, handlers and serverConfig sections. The bindings configuration is appended to the parent configuration. The handlers and serverConfig configuration is merged with the parent configuration.

In an example project we have the following ratpack.groovy, that includes two extra files: course.groovy and loghandler.groovy:

Continue reading →

Ratpacked: Revisited Using Multiple DataSources

Posted on by  
Hubert Klein Ikkink

In a previous post we learned how to add an extra DataSource to our Ratpack application. At that time on the Ratpack Slack channel there was a discussion on this topic and Danny Hyun mentioned an idea by Dan Woods to use a Map with DataSource objects. So it easier to add more DataSource and Sql objects to the Ratpack registry. In this post we are going to take a look at a solution to achieve this.

We are going to use the HikariDataSource, because it is fast and low on resources, in our example code. First we create a new class to hold the configuration for multiple datasources. The configuration is a Map where the key is the name of the database and the value an HikariConfig object. The key, the name of the database, is also used for creating the HikariDataSource and Sql objects. And the good thing is that Ratpack uses a Jackson ObjectMapper to construct a configuration object and it understands Map structures as well. In the ratpack.groovy file at the end of this blog post we see how we can have a very clean configuration this way.

Continue reading →

Ratpacked: Using Multiple DataSources

Posted on by  
Hubert Klein Ikkink

Recently on our project where we use Ratpack we had to get data from different databases in our Ratpack application. We already used the HikariModule to get a DataSource to connect to one database. Then with the SqlModule we use this DataSource to create a Groovy Sql instance in the registry. In our code we use the Sql object to query for data. To use the second database we used the Guice feature binding annotations to annotate a second DataSource and Sql object. In this post we see how we can achieve this.

Interestingly while I was writing this post there was a question on the Ratpack Slack channel on how to use multiple datasources. The solution in this post involves still a lot of code to have a second DataSource. In the channel Danny Hyun mentioned a more generic solution involving a Map with multiple datasources. In a follow-up blog post I will write an implementation like that, so we have a more generic solution, with hopefully less code to write. BTW the Ratpack Slack channel is also a great resource to learn more about Ratpack.

Continue reading →

Ratpacked: Customising Renderers With Decorators

Posted on by  
Hubert Klein Ikkink

When we use the Context.render method Ratpack's rendering mechanism kicks in. The type of the argument we pass to the render method is used to look up the correct renderer. The renderer implements the Renderer interface and provides the real output. We can add functionality that can work with the object of the Renderer implementation before the actual output is created. We do this by adding a class or object to the registry that implements the RenderableDecorator interface. The interface has a method decorate that accepts the Context and object that needs to be rendered. The code is invoked after the Context.render method, but before the Renderer.render method. This is especially useful when we use template renderers with a view model and with a RenderableDecorator implementation we can augment the view model with some general attributes. Suppose we have a Ratpack application that uses the Groovy text template engine provided by the TextTemplateModule. The module adds a Renderer for TextTemplate objects. Let's write a RenderableDecorator implementation for the TextTemplate, where we add an extra attribute createdOn to the view model:

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

import ratpack.exec.Promise
import ratpack.groovy.template.TextTemplate
import ratpack.handling.Context
import ratpack.render.RenderableDecorator

import java.time.Clock
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter

/**
 * Add extra attribute to view model for all TextTemplate renderers.
 */
class CreatedOnRendererDecorator implements RenderableDecorator {

    /**
     * Apply this decorator for TextTemplate renderers.
     *
     * @return TextTemplate class.
     */
    @Override
    Class getType() {
        return TextTemplate
    }

    /**
     * Add an extra attribute createdOn to the view model with the current
     * date and time.
     *
     * @param context Context to get Clock instance for this Ratpack application from.
     * @param template Template with view model to extend.
     * @return Promise with new TextTemplate instance with the extended view model.
     */
    @Override
    Promise decorate(final Context context, final TextTemplate template) {
        final footerModel = [createdOn: createdOn(context)]

        return Promise.value(
                new TextTemplate(
                        template.model + footerModel,
                        template.id,
                        template.type))
    }

    /**
     * Create formatted date/time String based on
     * the Clock available on the Ratpack registry.
     *
     * @param context Context to get Clock instance from.
     * @return Formatted date/time String.
     */
    private String createdOn(final Context context) {
        final Clock clock = context.get(Clock)
        final LocalDateTime now = LocalDateTime.now(clock)
        final DateTimeFormatter formatter =
                DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        return formatter.format(now)
    }

}

Continue reading →

Ratpacked: Add Chains Via Registry

Posted on by  
Hubert Klein Ikkink

In a previous blog post we learned how to use HandlerDecorator.prepend to add common handlers via the registry in our application. The type of handlers suitable for this approach were handlers that had common functionality for the rest of the handlers. If we want to add a Chain implementation, containing handlers and maybe even path information, we cannot use the prepend method, must write our own implementation of the HandlerDecorator interface. This can be useful when we want to re-use a Chain in multiple applications. We write a module that adds the Chain implementation to the registry and we don't have to write any code in the handlers section for the Chain to work. This blog post is inspired by a conversation on the Ratpack Slack channel recently. First we create a simple handler that renders a result:

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

import ratpack.groovy.handling.GroovyChainAction

/**
 * Implementation of a {@link ratpack.handling.Chain} interface
 * by extending {@link GroovyChainAction}, so
 * we can use Groovy DSL support in the
 * {@link Ping#execute} method.
 */
class Ping extends GroovyChainAction {

    @Override
    void execute() throws Exception {
        // What we normally would write
        // in the handlers{} section
        // of Ratpack.groovy.
        path('pingpong') {
            render 'Ratpack rules!'
        }
    }
}

Continue reading →

shadow-left