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.