Rich Sadowsky
Rich Sadowsky

Reputation: 955

Can Grails Command Objects have variable number of parameters?

We are using Command Objects with Grails controllers in Grails 2.0.1. This is fantastic feature and has led to very nice, concise controllers with fully validated parameters. I have a case where there is a web service call implemented in a controller where there are a few fixed parameters and then a number of variable length parameters. I've googled all over the place and can't seem to find an example. The grails docs are fairly terse on command objects in general. I can do what I'd like without Command objects, but then I would break the pattern in this set of controllers where every other call uses a Command Object. FWIW this particular call is a POST that is submitting data to the backend. There is no Domain object here, the data is being transformed into a row in a spreadsheet. We certainly could make a Domain object to model the data but I am not sure if that helps solve the problem in any way.

I'm not sure a code sample would help but here is one anyway:

package com.companyname.platform.api

    class ApiController {
        static allowedMethods = [save:'POST', close:'POST', storeResults: 'POST']

        def save = { APISaveCommand cmd->
            doSaveAction(cmd)
        }
        def close = APICloseCommand cmd->
            doCloseAction(cmd)
        }
        def storeResults = { params->
            doStoreResults(params)
        }
    }
}

See how the storeResults doesn't have a Command object? It takes variable number of parameters. In the above code assume the do*Action methods are in a Service that has been injected into this controller. Nothing wrong with doStoreResults(params), but I really would love to stick with command object pattern.

Upvotes: 3

Views: 728

Answers (1)

user800014
user800014

Reputation:

According to you comment, yes it's possible to use commands in this case. Juts declare all fields in the command and implement custom validators to the fields that have to be declared in pairs.

In a validator you have access of the field value and also the object instance, so you can easily compare if one of them is null and the other is not null.

@Validateable
class MyCommand {
  String a
  String b
  String c

  static constraints = {
    a nullable: false, blank: false
    b validator: { val, obj ->
      if((!val && obj.c) || (val && !obj.c)) {
        return 'mycommand.declareBAndC.message' //key to the i18n message
      }
    }
  }

}

Upvotes: 1

Related Questions