Home » JVM Languages » Groovy » Grails tip: refactoring your URLs

About Alex Staveley

Alex Staveley

Grails tip: refactoring your URLs

On the current project I am working we use a lot of integration tests. For you non-Grails users out there, Integration tests test your Controller APIs, your Services and any persistence that might happen all very neatly. The only slice of the cake they don’t test from a back end perspective are your Grails filters for which you’d need something like a functional test. In the Grails world, Controller API’s are mapped to URL requests in the URLMappings.groovy file. This is just a simple Groovy to configure which HTTP request go to which Controller.

For example:

class UrlMappings {
    static mappings = {
        "/sports/rugby/ball" (controller: "rugbyBall", action = [POST: "createBall", DELETE: "removeBall", GET: "getBall"])

So in the above example, the HTTP request /sports/rugby/ball will go to the RugbyBallController and will go to the methods: createBall(), deleteBall(), getBall() depending on weather the request is a GET, POST or DELETE. Now suppose, you have your project all set up to server up the CRUD operations for the rugby ball and after a few hectic sprints some software entropy creeps and you need to refactor your Controller APIs but before you race ahead and do that your project manager looks you in the eye and says: “You must support all existing APIs as clients are using them”.
This is how generally refactoring works in the real world when things go into production. There is always a phase of supporting the old and new, deprecating the old and then when everyone is happy removing it. Anyway, you begin by updating your URLMappings.groovy

class UrlMappings {
    static mappings = {
        // Old APIs
        "/sports/rugby/ball" ( controller: "rugbyBall", action = [POST: "oldCreateBall", DELETE: "oldRemoveBall", GET: "oldGetBall"])

        // New APIs
        "/sports/rugby/v2/ball" ( controller: "rugbyBall", action = [POST: "createBall", DELETE: "removeBall", GET: "getBall"])

The URLMappings.groovy show the old and the new. The old APIs are going to controller methods that you have renamed. Clients using these APIs are not impacted because they only send HTTP requests, they do not know which Controller is behind these endpoints. The old APIs already have really good integration tests and our project manager has mandated that the new APIs must have similar quality integration tests before they go anywhere near pre-production.

def "test adding a single item to your cart"() {
    setup: "Set up the Cart and Landing Controller"
       rugbyBall = JSON.parse(rugbyBallController.response.contentAsString)

Mr. Project manager says: “I want all these new tests added by Friday or you are not going for a pint after work. You need a quick way to get your integration tests done”. Thinking about that cool lager and its quenching effect on the back of your throat, you remember Groovy’s excellent support for invoking methods dynamically where you can specify the name of the method as a variable.

myObject."$myMethod"()  // myMethod is a Groovy String variable.

In the above code snippet, myMethod is a variable that corresponds to the name of method you want to invoke on myObject. “$myMethod” means, evaluate the variable myMethod (which of course will be the method name), the () of course just means invokes the method. Eureka moments happens when you remember that the old and new APIs will return the exact same JSON. All you need to do is run the same test twice, once for the old code and once for the new. Since you are using the spock framework for your integration tests that’s easily achieved using a where block.

def "test adding a single item to your cart"(String method) {
    setup: "Set up the Cart and Landing Controller"
       rugbyBall = JSON.parse(rugbyBallController.response.contentAsString)
       method = ["oldGetBall", "getBall"]

Happy days. Now go off and drink that lager.

Reference: Grails tip: refactoring your URLs from our JCG partner Alex Staveley at the Dublin’s Tech Blog blog.

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you our best selling eBooks for FREE!


1. JPA Mini Book

2. JVM Troubleshooting Guide

3. JUnit Tutorial for Unit Testing

4. Java Annotations Tutorial

5. Java Interview Questions

6. Spring Interview Questions

7. Android UI Design


and many more ....



Leave a Reply

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


Want to take your Java skills to the next level?

Grab our programming books for FREE!

Here are some of the eBooks you will get:

  • Spring Interview QnA
  • Multithreading & Concurrency QnA
  • JPA Minibook
  • JVM Troubleshooting Guide
  • Advanced Java
  • Java Interview QnA
  • Java Design Patterns