ankit ankit - 3 months ago 16
Groovy Question

Can groovy support both varargs and default parameters?

I want to create a generic REST api method like:

List<T> fetchResponse(HttpMethod requestType, Class<T> typeParam, String format = null, String urlSuffix, Object... params) {
...
}


The 'format' will be present only when I expect Dates in the response and need to parse them correctly. The params will always be strings as well. My concern is that this will create ambiguities about which values correspond to which attributes at runtime. Will this work?

Answer

There is support for both but there can be confusion for the client coder. I have written some mock classes to illustrate. First, if I want to omit format, specify urlSuffix, and provide 2 params, I might try:

fetcher.fetchResponse(hm, String.class, "x", "y", "z")

However, observe the assertions:

class HttpMethod {}

class Fetcher<T> {
    def args = [:]
    List<T> fetchResponse(HttpMethod requestType, 
                          Class<T> typeParam, 
                          String format = null, 
                          String urlSuffix, 
                          Object... params) {
        args["requestType"] = requestType
        args["typeParam"] = typeParam
        args["format"] = format
        args["urlSuffix"] = urlSuffix
        args["params"] = params
    }
}

def hm = new HttpMethod()
def fetcher = new Fetcher<String>()
fetcher.fetchResponse(hm, String.class, "x", "y", "z")

assert hm == fetcher.args["requestType"]
assert String.class == fetcher.args["typeParam"]
assert "x" == fetcher.args["format"]
assert "y" == fetcher.args["urlSuffix"]
assert ["z"] == fetcher.args["params"]

Note that format is "x". If one changes the order of the signature to be (httpMethod, format = null, typeParam, urlSuffix, params), then this might be acceptable:

fetcher.fetchResponse(hm, String.class, "x", "y", "z")

assert hm == fetcher.args["requestType"]
assert null == fetcher.args["format"]
assert String.class == fetcher.args["typeParam"]
assert "x" == fetcher.args["urlSuffix"]
assert ["y", "z"] == fetcher.args["params"]

An alternative is to accept a Map as a parameter to the method, and then use named parameters:

fetcher.fetchResponse(requestType: hm, urlSuffix: "x", typeParam: String.class, params: ["y", "z"])

(This option is not entirely related to your question, but might be easier for clients.)