3
votes

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.

1
There is no way to have a command object with dynamic attributes - James Zhang
If you don't know what's coming in the params, why you need a command? Will you perform some custom validation? - user800014
Sorry if I implied I don't know what's coming. There are a number of fixed parameters which are required and should be validated. But there are a number of extra parameters that may or may not be included. The nature of these parameters is that even the variable ones would benefit from validation since they have to come in pairs. It seems like this isn't a particularly unique use case. The good news is this is easy enough to handle using the generic object "params" as shown in storeResults. But it's sad I can't use the very powerful Grails command object. - Rich Sadowsky

1 Answers

1
votes

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
      }
    }
  }

}