Ratpack is a lean framework. To add extra functionality, like using a database, we can use framework modules. Ratpack comes with a couple of framework modules. One of the modules is the SqlModule
. This module adds a Groovy Sql
instance to our application. We can use it to execute SQL code against a database. The SqlModule
needs a DataSource
instance, so we need to write some code to provide a DataSource
instance for a PostgreSQL database.
First we add the JDBC drivers for PostgreSQL to our Gradle build file:
// File: build.gradle ... dependencies { ... compile 'org.postgresql:postgresql:9.4-1205-jdbc42' ... } ...
Next we create a configurable module to provide a DataSource
instance for our application. We write a class with configuration properties and a module class that uses the class with configuration properties.
// File: src/main/groovy/com/mrhaki/ratpack/postgres/PostgresConfig.groovy package com.mrhaki.ratpack.postgres import groovy.transform.CompileStatic @CompileStatic class PostgresConfig { String user String password String serverName = 'localhost' String databaseName Integer portNumber = 5432 }
// File: src/main/groovy/com/mrhaki/ratpack/postgres/PostgresModule.groovy package com.mrhaki.ratpack.postgres import com.google.inject.Provides import groovy.transform.CompileStatic import org.postgresql.ds.PGSimpleDataSource import ratpack.guice.ConfigurableModule import javax.sql.DataSource /** * Module to create DataSource instance for PostgreSQL database. */ @CompileStatic class PostgresModule extends ConfigurableModule<PostgresConfig> { @Override protected void configure() { } /** * Create DataSource instance. * * @param config Configuration object with properties for creating DataSource. * @return DataSource for connecting to PostgreSQL database. */ @Provides DataSource dataSource(final PostgresConfig config) { createDataSource(config) } /** * Subclasses can override this method to create other DataSource * instance, e.g. PGPoolingDataSource. * * @param config Configuration object with properties for creating DataSource. * @return DataSource for connecting to PostgreSQL database. */ protected DataSource createDataSource(final PostgresConfig config) { new PGSimpleDataSource( user: config.user, password: config.password, serverName: config.serverName, databaseName: config.databaseName, portNumber: config.portNumber) } }
Let's see how we can add this module to our Ratpack application. We use the Groovy DSL for our application. The following snippet of the bindings
block uses the module
method to add our PostgresModule
:
// File: src/ratpack/Ratpack.groovy import com.mrhaki.ratpack.postgres.PostgresConfig import com.mrhaki.ratpack.postgres.PostgresModule import ratpack.config.ConfigData import ratpack.config.ConfigDataBuilder import ratpack.groovy.sql.SqlModule import static ratpack.groovy.Groovy.ratpack ratpack { bindings { // Create generic configuration. final ConfigData configData = ConfigData.of { ConfigDataBuilder builder -> // Set configuration properties. // We can use the yaml, json and other // ConfigDataBuilder methods to read // configuration from other sources. builder.props( ['postgres.user' : 'postgres', 'postgres.password' : 'secret', 'postgres.portNumber' : 5432, 'postgres.databaseName': 'postgres', 'postgres.serverName' : '192.168.99.100']) builder.build() } // Create instance of PostgresConfig // that is used for the // configurable module PostgresModule. bindInstance PostgresConfig, configData.get('/postgres', PostgresConfig) // Initialise module to create DataSource. module PostgresModule // Initialize SqlModule to provide // Groovy SQL support in our application. module SqlModule } ... }
The DataSource
we created is very simple and doesn't support connection pooling. Ratpack has a framework module to add connection pooling support from the Hikari library to our application. Hikari is a solid, high performance JDBC connection pooling framework. To add it to our application we must add a dependency to our Gradle build file and add the module in our bindings
block.
// File: build.gradle ... dependencies { ... // Use Ratpack extension for including // dependency to Hikari with correct // version for the Ratpack version we use. compile ratpack.dependency('hikari') ... } ...
We re-use our PostgresModule
class to set the dataSource
property of the Hikara configuration:
// File: src/ratpack/Ratpack.groovy import com.mrhaki.ratpack.postgres.PostgresConfig import com.mrhaki.ratpack.postgres.PostgresModule import com.zaxxer.hikari.HikariConfig import ratpack.config.ConfigData import ratpack.config.ConfigDataBuilder import ratpack.groovy.sql.SqlModule import ratpack.hikari.HikariModule import static ratpack.groovy.Groovy.ratpack ratpack { bindings { // Create generic configuration. final ConfigData configData = ConfigData.of { ConfigDataBuilder builder -> // Set configuration properties. // We can use the yaml, json and other // ConfigDataBuilder methods to read // configuration from other sources. builder.props( ['postgres.user' : 'postgres', 'postgres.password' : 'secret', 'postgres.portNumber' : 5432, 'postgres.databaseName': 'postgres', 'postgres.serverName' : '192.168.99.100']) builder.build() } // Configure HikariModule. There are different // ways to set properties. Here we assign // a DataSource instance to the dataSource property. module HikariModule, { HikariConfig config -> config.dataSource = new PostgresModule().dataSource( configData.get('/postgres', PostgresConfig)) } // Initialize SqlModule to provide // Groovy SQL support in our application. module SqlModule } ... }
Written with Ratpack 1.1.1.