Search

Dark theme | Light theme
Showing posts with label Ratpacked:Paths. Show all posts
Showing posts with label Ratpacked:Paths. Show all posts

December 22, 2015

Ratpacked: Using Names With Regular Expression Tokens

In a previous post we have seen how to use regular expressions for path tokens. We can also name the path token for which the regular expression applies. This makes it easier to get the value in our handler code: we can just refer to the name. Also we can add a question mark to the name to make the token optional.

In the following example we use the name conferenceName for the path token with the regular expression Gr\w+:

import ratpack.groovy.template.MarkupTemplateModule
import ratpack.handling.Context
import ratpack.path.PathBinder
import ratpack.path.PathBinding

import static ratpack.groovy.Groovy.groovyMarkupTemplate
import static ratpack.groovy.Groovy.ratpack

ratpack {
    handlers {

        prefix('conferences') {
            // Here we define a path with the named 
            // token conferenceName.
            path(/:conferenceName:Gr\w+/) { 
                // The token has a name and a regular expression.
                // If the value matches the regular expression,
                // we can refer to the value using the name.
                final String conferenceName = pathTokens.conferenceName
                
                // Use matched value in response.
                render "Conference($conferenceName)"
            }
        }

    }
}

Written with Ratpack 1.1.1.

November 16, 2015

Ratpacked: Using Optional Path Tokens

To define endpoints in our Ratpack application we can use optional path tokens. This means that a part of the request can have a value or not, but we can a have single path definition that will match. Normally we define a variable path token with a colon (:) followed by a variable name. To make this token optional we follow it with a question mark (?). This tells Ratpack that the token can have a value or not. In our handler we now need to take into account that the path token is optional as well.

Let's write a sample Ratpack application with a path definition containing an optional token. We define a path binding for profiles/:username?. The path token username is available in our handler if the value is set, but also a request for profiles will match for this binding. Then the value for username is not set.

// File: src/ratpack/Ratpack.groovy
import static ratpack.groovy.Groovy.ratpack

ratpack {

    handlers {

        // Specify the optional path token username.
        // This path definition will match for 
        // request paths like profiles/mrhaki and
        // profiles (without slash and username value).
        path('profiles/:username?') {

            // Simply render the value of the username
            // path token if set, otherwise return "all"
            render pathTokens.getOrDefault('username', 'all')
        }

    }
}

We write the following test to check the different responses we get when we provide values for the optional token or leave out a value:

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

import ratpack.groovy.test.GroovyRatpackMainApplicationUnderTest
import spock.lang.AutoCleanup
import spock.lang.Shared
import spock.lang.Specification
import spock.lang.Unroll

class OptionalPathBindingSpec extends Specification {

    @AutoCleanup
    @Shared
    GroovyRatpackMainApplicationUnderTest app = 
            new GroovyRatpackMainApplicationUnderTest()

    @Unroll('path #path should return "#expectedResponse"')
    def "check response for request with and without optional token"() {
        when:
        def response = app.httpClient.get(path)

        then:
        response.body.text == expectedResponse

        where:
        path                  || expectedResponse
        '/profiles/mrhaki'    || 'mrhaki'
        '/profiles/hubert'    || 'hubert'
        '/profiles'           || 'all'
        '/profiles/'          || ''
        '/profiles/mrhaki/42' || 'Client error 404'
    }
    
}

Written with Ratpack 1.1.1.