3

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.

Rich Sadowsky
  • 966
  • 1
  • 12
  • 22
  • There is no way to have a command object with dynamic attributes – James Zhang Dec 10 '12 at 18:37
  • If you don't know what's coming in the params, why you need a command? Will you perform some custom validation? –  Dec 10 '12 at 21:55
  • 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 Dec 11 '12 at 05:17

1 Answers1

1

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

}
  • Hmm, maybe I misspoke. I know all the fixed params that are coming, and I know the nature of the variable component, but I don't know how many of them there would be. So using your example I'd have to declare strings a..z and then I would be limited to 26 of the variable pairs. We've considered that because for all practical purposes there is a likely top end. But I really want to know if variable number of params are possible. I think this is a feature that would come in handy. I have come up with a couple of ways this might be done. It's not giving me enough space in the comment to explain! – Rich Sadowsky Dec 11 '12 at 19:27
  • hmm, are you saying that may have n times a in the params? Something like a[0] = xxx, a[1] = xxx, a[2] = xxx? –  Dec 11 '12 at 19:48
  • yes something like that. Imagine that you have some fixed data that is demographic data like age, gender, location. Now imagine that the user can request information. When done they are offered more info. So the amount of info they request could be 1 item or 200 items. But the data is all closely related and part of a simple POST from a tablet. I can easily implement this by using the storeResults with an untyped params object (see OP), but I really dig the functionality of the Command Objects. I don't think my use case is all that unique. I think others will have similar uses for Command Objs – Rich Sadowsky Dec 11 '12 at 21:58