Using Flyway for database migrations in Ratpack apps

For Ratpack applications that use a database, it’s handy to be able to sync database changes with code changes. Using database migration files is a great way to accomplish that. Flyway is a simple library for doing database migrations in JVM applications that we can easily integrate into a Ratpack app. In this post we’ll go through steps to use Flyway in a Ratpack app.

First, we need to add the Flyway dependency to our build.gradle file:

dependencies {
  compile 'org.flywaydb:flyway-core:4.0.3'
  ...
}

Next, let’s a database migration file. By default, Flyway looks for the migrations in the src/main/resources/db/migration folder, so let’s create that folder.

Flyway uses ‘versions’ of a schema to know which migration files to run. For example, if the database is currently on version 4 and there are migration files up through version 7, it will run migrations 5, 6, and 7. The migration version is indicated by the start of the filename – “V1__create_status_item_table.sql” is an example version 1 migration file name. Flyway keeps track of the version in a metadata table “schema_version” that it will create automatically if it doesn’t find the table.

And example migration V1__create_status_item_table.sql file that creates a table:

CREATE TABLE status_item(
  id INT PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR(255),
  completed_yesterday VARCHAR(255),
  working_on_today VARCHAR(255),
  impediments VARCHAR(255),
  date_created TIMESTAMP
)

Now let’s configure our Ratpack app to run the database migrations on app startup. In our example, we’ve configured an in-memory H2 database datasource in src/ratpack/ratpack.groovy

import org.h2.jdbcx.JdbcDataSource
import javax.sql.DataSource
 
ratpack {
    bindings {
        bindInstance(DataSource, new JdbcDataSource(
                URL: "jdbc:h2:mem:test;DB_CLOSE_DELAY=-1",
                user: "sa",
                password: ""
        ))
    }
}

And let’s create a DatabaseMigrationService that will participate in the Ratpack application lifecycle and run the migrations when the app starts. By implementing the ratpack.service.Service interface and defining an onStart() method, Ratpack will automatically call our migration code when the application starts.

import org.flywaydb.core.Flyway
import ratpack.service.Service
import ratpack.service.StartEvent
 
import javax.sql.DataSource
 
class DatabaseMigrationService implements Service {
    void onStart(StartEvent e) {
        DataSource dataSource = e.registry.get(DataSource)
 
        Flyway flyway = new Flyway()
 
        flyway.setDataSource(dataSource)
 
        flyway.migrate()
    }
}

As you can see, configuring Flyway and running the migrations is very simple. We just need to grab the DataSource bean that we configured in ratpack.groovy out of the registry and configure the Flyway object with it. Then call flyway.migrate() and that’s it!

Last but not least, we’ll add our DatabaseMigrationService to the bindings list in ratpack.groovy

import org.h2.jdbcx.JdbcDataSource
import javax.sql.DataSource
 
ratpack {
    bindings {
        bindInstance(DataSource, new JdbcDataSource(
                URL: "jdbc:h2:mem:test;DB_CLOSE_DELAY=-1",
                user: "sa",
                password: ""
        ))
        bindInstance(new DatabaseMigrationService())
    }
}

Now when we start up our Ratpack app and see log output like the following

[ratpack-compute-1-1] INFO org.flywaydb.core.internal.util.VersionPrinter - Flyway 4.0.3 by Boxfuse
[ratpack-compute-1-1] INFO org.flywaydb.core.internal.dbsupport.DbSupportFactory - Database: jdbc:h2:mem:test (H2 1.4)
[ratpack-compute-1-1] INFO org.flywaydb.core.internal.command.DbValidate - Successfully validated 1 migration (execution time 00:00.012s)
[ratpack-compute-1-1] INFO org.flywaydb.core.internal.metadatatable.MetaDataTableImpl - Creating Metadata table: "PUBLIC"."schema_version"
[ratpack-compute-1-1] INFO org.flywaydb.core.internal.command.DbMigrate - Current version of schema "PUBLIC": << Empty Schema >>
[ratpack-compute-1-1] INFO org.flywaydb.core.internal.command.DbMigrate - Migrating schema "PUBLIC" to version 1 - create status item table
[ratpack-compute-1-1] INFO org.flywaydb.core.internal.command.DbMigrate - Successfully applied 1 migration to schema "PUBLIC" (execution time 00:00.053s).

The full code for this Ratpack application is on Github. Hope this post helps!

About the Author

Object Partners profile.

One thought on “Using Flyway for database migrations in Ratpack apps

  1. Jonny A says:

    Helped me out and got me moving quickly. Thanks. I wish I knew who wrote it so I could thank them.

Leave a Reply

Your email address will not be published. Required fields are marked *

Related Blog Posts
AWS Cloud HSM, Docker and NGINX
There is quite a bit of easily searchable content on the security benefits of leveraging a Hardware Security Module to manage cryptographic keys, so I will leave that to the scope of another article. The […]
Google Professional Machine Learning Engineer Exam 2021
Exam Description A Professional Machine Learning Engineer designs, builds, and productionizes ML models to solve business challenges using Google Cloud technologies and knowledge of proven ML models and techniques. The ML Engineer is proficient in all aspects […]
Designing Kubernetes Controllers
There has been some excellent online discussion lately around Kubernetes controllers, highlighted by an excellent Speakerdeck presentation assembled by Tim Hockin. What I’d like to do in this post is explore some of the implications […]
React Server Components
The React Team recently announced new work they are doing on React Server Components, a new way of rendering React components. The goal is to create smaller bundle sizes, speed up render time, and prevent […]