[groovy-user] No signature of method: groovyx.net.http.RESTClient.xxx() is applicable for argument types?

461 views
Skip to first unread message

Richard Osbaldeston

unread,
Jun 17, 2010, 9:51:33 AM6/17/10
to us...@groovy.codehaus.org

Having some problems reading responses from RESTClient where I keep running into errors like:

groovy.lang.MissingMethodException: No signature of method: groovyx.net.http.RESTClient.put() is applicable for argument types: (java.util.LinkedHashMap, ConsoleScript5$_run_closure1) values: [[path:foo/bar/baz, query:[format:xml], body:[description:], requestContentType:application/x-www-form-urlencoded], ConsoleScript5$_run_closure1@1441b16]

e.g.

<code>
@Grab(group='org.codehaus.groovy.modules.http-builder', module='http-builder', version='0.5.0' )

def api = new groovyx.net.http.RESTClient('http://localhost:8080/resources/')
api.auth.basic 'scott', 'tiger'
def resp = api.put(path: "foo/bar/baz",
        query: [format: 'xml'],
        body: [description: ''],
        requestContentType: groovyx.net.http.ContentType.URLENC) { resp, xml ->
  assert resp.status==201
  def result = new groovy.xml.StreamingMarkupBuilder().bindNode(xml).toString()
}
</code>

In this case I'm trying to read from a PUT although I've used very similar code elsewhere to read from the get method. I'm kinda confused as to what the syntax is doing. The resp return value is a HttpResponseDecorator I guess, but I dont know quite where xml is coming from is HttpResponseDecorator also a closure of some kind? I dont see an xml property on it?

I've also been getting "No signature of method: groovyx.net.http.RESTClient.get() is applicable for argument types" errors on similarly formed RESTClient.get methods via the dev snapshot of GR-ECLIPSE, while the same code would work in GroovyConsole or JetGroovy.. None of which will run the put() example above BTW. 

Guess I'm after a little understanding as to how the read what the RESTClient methods are doing/returning and how to square that with HttpBuilders JavaDocs. Or if I'm doing something stupid - thats more than possible too.

- Richard

Thom Nichols

unread,
Jun 17, 2010, 10:07:58 AM6/17/10
to user

RESTClient's get/put/post/delete methods do not take a closure argument.  You're thinking of HTTPBuilder.  See:
http://groovy.codehaus.org/modules/http-builder/doc/rest.html
and
http://groovy.codehaus.org/modules/http-builder/apidocs/groovyx/net/http/RESTClient.html#method_summary

Try it like this:

def api = new groovyx.net.http.RESTClient('http://localhost:8080/resources/')
api.auth.basic 'scott', 'tiger'
def resp = api.put(path: "foo/bar/baz",
        query: [format: 'xml'],
        body: [description: ''],
        requestContentType: groovyx.net.http.ContentType.URLENC)

assert resp.status==201
def result = new groovy.xml.StreamingMarkupBuilder().bindNode(resp.data).toString()

Richard Osbaldeston

unread,
Jun 17, 2010, 10:34:11 AM6/17/10
to us...@groovy.codehaus.org
Yes that works thanks, so data===xml that'll give me something to think about. Guess I can use this syntax for all my get() methods too, hopefully avoiding the similar looking exceptions GR-ECLIPSE was throwing. 

Was using bindNode because I also didnt have a clue what mkp.yield was all about as in: String result = new StreamingMarkupBuilder().bind { mkp.yield xml } also Jetgroovy didnt recognize mkp

- Richard

Thom Nichols

unread,
Jun 17, 2010, 11:04:19 AM6/17/10
to user
So resp.data == xml if your response is XML :)  If the response format was JSON, resp.data would be a groovy object parsed by Json-Lib.  The documentation here:
http://groovy.codehaus.org/modules/http-builder/apidocs/groovyx/net/http/RESTClient.html#get(java.util.Map)
and here: http://groovy.codehaus.org/modules/http-builder/apidocs/index.html?groovyx/net/http/RESTClient.html
attempt to explain that get/post/put etc return a HttpResponseDecorator object.  So "resp instanceof HttpResponseDecorator". 

Responses are expected to either not carry data (in the case of HEAD or DELETE) or be parse-able into some sort of object (in the case of GET and sometimes POST/PUT). That object is accessible via HttpResponseDecorator.getData(). By default, all request method methods will return a HttpResponseDecorator instance, which provides convenient access to response headers and the parsed response body.

As far as bindNode, I _think_ that's the correct way to take a parsed GPathResult and re-create the original XML text.  And I think the mkp.yield call isn't recognized because 'mkp' is a property of the closure's delegate which is set at runtime.  So unless the IDE has special knowledge of how StreamingMarkupBuilder works, it would never know what mkp is.  Nature of dynamic languages I guess. 
Reply all
Reply to author
Forward
0 new messages