Ratpacked: Using PostgreSQL Database
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 {
@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.