Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Ratpacked: Apply Configuration To Configurable Module

DZone's Guide to

Ratpacked: Apply Configuration To Configurable Module

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

Free Resource

Modernize your application architectures with microservices and APIs with best practices from this free virtual summit series. 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 proudly sponsored by CA Technologies. Learn from expert microservices and API presentations at the Modernizing Application Architectures Virtual Summit Series.

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 DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

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

X

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

{{ parent.tldr }}

{{ parent.urlSource.name }}