November 16, 2015

Ratpacked: Using Regular Expressions For Path Tokens

When we define a path in Ratpack we can use regular expressions for matching a request. We must start a token with a double colon (::) and then we can define a regular expression. Ratpack will try to match the request path and uses our regular expression.

In the following example Ratpack application we use a regular expression to match requests that start with Gr after a fixed conferences prefix:

// File: src/ratpack/Ratpack.groovy
import ratpack.path.PathBinding
import ratpack.handling.Context

import static ratpack.groovy.Groovy.ratpack

ratpack {

    handlers {

        prefix('conferences') {
            path(/::Gr\w+/) { Context ctx ->
                // The token has not a name, like with a 
                // normally defined token that is defined
                // with a single colon (:).
                // So we need to get the value via 
                // the PathBinding instance.
                final PathBinding binding = ctx.get(PathBinding)
                // With the boundTo property of PathBinding
                // we get the value that matches the 
                // regular expression.
                final String conferenceName = binding.boundTo
                // Use matched value in response.
                render "Conference($conferenceName)"


With the following specification we can test our definition:

// File: src/test/groovy/com/mrhaki/ratpack/pathbinding/RegExPathSpec.groovy
package com.mrhaki.ratpack.pathbinding

import ratpack.groovy.test.GroovyRatpackMainApplicationUnderTest
import ratpack.http.client.ReceivedResponse
import ratpack.test.http.TestHttpClient
import spock.lang.AutoCleanup
import spock.lang.Shared
import spock.lang.Specification

class RegExPathSpec extends Specification {

    GroovyRatpackMainApplicationUnderTest app =
            new GroovyRatpackMainApplicationUnderTest()

     * Delegate HTTP calls to TestHttpClient instance.
    TestHttpClient httpClient = app.httpClient

    def "check valid regular expression values"() {
        final ReceivedResponse response = get(conferenceName)

        response.body.text == responseText
        response.statusCode == 200

        conferenceName        || responseText
        'conferences/Gr8Conf' || 'Conference(Gr8Conf)'
        'conferences/Greach'  || 'Conference(Greach)'

    def "if value doesn't match regular expression return 404"() {
        final ReceivedResponse response = get('conferences/JavaOne')

        response.statusCode == 404


Written with Ratpack 1.1.1.