Over a million developers have joined DZone.

Ratpacked: Apply Configuration To Configurable Module

Here's how to use a configurable module in Ratpacked.

Build APIs from SQL and NoSQL or Salesforce data sources in seconds. Read the Creating REST APIs white paper, brought to you in partnership with CA Technologies.

In Ratpack we can use Guice modules to organize code to provide objects to the registry. Ratpack adds configurable modules that take an extra configuration object. Values from the configuration object are used to create new objects that are provided to our application. Using the Groovy DSL we have several ways to make a configuration object available to a configurable module.

Let's create a sample configurable module and look at the different ways to give it a configuration object. We create a module, GreetingModule, that provides a Greetingobject. The configuration is defined in the class GreetingConfig.

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

import com.google.inject.Provides
import groovy.transform.CompileStatic
import ratpack.guice.ConfigurableModule

@CompileStatic
class GreetingModule extends ConfigurableModule<GreetingConfig>{
    
    @Override
    protected void configure() {}
    
    /**
     * Method to create a new Greeting object with values
     * from the GreetingConfig configuration object.
     */
    @Provides
    Greeting greeting(final GreetingConfig config) {
        new Greeting(message: "${config.salutation}, ${config.message}")
    }
    
}
// File: src/main/groovy/com/mrhaki/ratpack/GreetingConfig.groovy
package com.mrhaki.ratpack

import groovy.transform.CompileStatic

/**
 * Configuration properties for creating
 * a {@link Greeting} object using the
 * configurable module {@link GreetingModule}.
 */
@CompileStatic
class GreetingConfig {
    String message
    String salutation
}
// File: src/main/groovy/com/mrhaki/ratpack/Greeting.groovy
package com.mrhaki.ratpack

import groovy.transform.CompileStatic

/**
 * Simple class with a greeting message.
 * The {@link GreetingModule} module creates
 * an instance of this class.
 */
@CompileStatic
class Greeting {
    String message
}

We have our configurable module and the supporting classes. Now we define the configuration and module in the bindings block of our Ratpack Groovy application. We use the ConfigData class to set configuration properties we later bind to theGreetingConfig object. With ConfigData we can define configuration properties from different sources, like files in Yaml, JSON or Java properties format. In our sample we simply define them using a Map. In the first sample we use the module method with a Closureargument to configure the GreetingModule

// File: src/ratpack/Ratpack.groovy
import com.mrhaki.ratpack.Greeting
import com.mrhaki.ratpack.GreetingConfig
import com.mrhaki.ratpack.GreetingModule
import ratpack.config.ConfigData
import ratpack.config.ConfigDataBuilder

import static ratpack.groovy.Groovy.ratpack

ratpack {
    bindings {
        final ConfigData configData = ConfigData.of { ConfigDataBuilder builder ->
            builder.props(
                    ['greeting.salutation': 'Hi',
                     'greeting.message'   : 'how are you doing?'])
            // We can also use external files, 
            // system properties and environment
            // variables to set configuration properties
            // inside this block.
            builder.build()
        }

        // The module methods allows a Closure argument to
        // set values for the supported configuration class.
        module GreetingModule, { GreetingConfig config ->
            config.salutation = configData.get('/greeting/salutation', String)
            config.message = configData.get('/greeting/message', String)
        }
    }

    handlers {
        // Simple handler using the created Greeting object.
        get { Greeting greeting ->
            render greeting.message
        }
    }
}

In the following sample we create an instance of GreetingConfig using thebindInstance method. The GreetingModule will pick up this instance and use it automatically:

// File: src/ratpack/Ratpack.groovy
import com.mrhaki.ratpack.Greeting
import com.mrhaki.ratpack.GreetingConfig
import com.mrhaki.ratpack.GreetingModule
import ratpack.config.ConfigData
import ratpack.config.ConfigDataBuilder

import static ratpack.groovy.Groovy.ratpack

ratpack {
    bindings {
        final ConfigData configData = ConfigData.of { ConfigDataBuilder builder ->
            builder.props(
                    ['greeting.salutation': 'Hi',
                     'greeting.message'   : 'how are you doing?'])
            // We can also use external files, 
            // system properties and environment
            // variables to set configuration properties
            // inside this block.
            builder.build()
        }

        // First create an instance of the GreetingConfig class. 
        bindInstance GreetingConfig, configData.get('/greeting', GreetingConfig)
        // With the module method we use the GreetingModule and
        // because there is a GreetingConfig instance available 
        // it is used to configure the module.
        module GreetingModule
    }

    handlers {
        // Simple handler using the created Greeting object.
        get { Greeting greeting ->
            render greeting.message
        }
    }
}

Finally we can use the moduleConfig method. This methods accepts a configuration object as an argument directly. So we can use an instance of GreetingConfig as method argument. We can also combine it with a Closure argument to override configuration properties:

// File: src/ratpack/Ratpack.groovy
import com.mrhaki.ratpack.Greeting
import com.mrhaki.ratpack.GreetingConfig
import com.mrhaki.ratpack.GreetingModule
import ratpack.config.ConfigData
import ratpack.config.ConfigDataBuilder

import static ratpack.groovy.Groovy.ratpack

ratpack {
    bindings {
        final ConfigData configData = ConfigData.of { ConfigDataBuilder builder ->
            builder.props(
                    ['greeting.salutation': 'Hi',
                     'greeting.message'   : 'how are you doing?'])
            // We can also use external files, 
            // system properties and environment
            // variables to set configuration properties
            // inside this block.
            builder.build()
        }

        // With the moduleConfig method we can pass an instance
        // of GreetingConfig directly.
        moduleConfig GreetingModule, configData.get('/greeting', GreetingConfig)

        // Or we can even combine it with a Closure argument to override a 
        // configuration property.
        //moduleConfig(
        //        GreetingModule, 
        //        configData.get('/greeting', GreetingConfig)) { GreetingConfig config ->
        //    config.message = 'Ratpack rocks!'
        //}
    }

    handlers {
        // Simple handler using the created Greeting object.
        get { Greeting greeting ->
            render greeting.message
        }
    }
}

The Integration Zone is brought to you in partnership with CA Technologies.  Use CA Live API Creator to quickly create complete application backends, with secure APIs and robust application logic, in an easy to use interface.

Topics:
ratpacked ,module ,configuration ,integration

Published at DZone with permission of Hubert Klein Ikkink, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}