Is it safe to reuse Groovy HTTPBuilder objects for multiple requests?

830 Views Asked by At

I have some HTTPBuilder code that behaves differently depending on whether or not I reuse the same HTTPBuilder object to perform two different requests to the same REST service:

def http = new HTTPBuilder( 'https://myBaseURI/' )
http.auth.basic username, password.getPlainText()
http.ignoreSSLIssues()

http.request(GET,JSON) { req ->
    uri.path = 'some/api/path/'
    headers.'User-Agent' = 'Mozilla/5.0'
} // this request always behaves as expected

http.request(POST, JSON) { req ->
    uri.path = 'some/other/api/path'
    headers.'User-Agent' = 'Mozilla/5.0'
    body = {
        // Request body elided for brevity
    }
}

The 'correct' behavior is for the POST to return a 201 - Created, but the response comes back as 200 OK unless I create a new HTTPBuilder to handle issuing the second request, in which case, the API call behaves as expected.

Certainly, the cause of the different results could be elsewhere, but I first wanted to make sure I wasn't misusing this object. Are there problems to be aware of when reusing the HTTPBuilder to issue multiple HTTP requests?

1

There are 1 best solutions below

0
On

Try removing that forward slash at the end when you set uri.path in the GET request.

Looking at the documentation for setPath in URIBuilder you get:

//Set the path component of this URI. The value may be absolute or relative to the current path. e.g.
   def uri = new URIBuilder( 'http://localhost/p1/p2?a=1' )

   uri.path = '/p3/p2'
   assert uri.toString() == 'http://localhost/p3/p2?a=1'

   uri.path = 'p2a'
   assert uri.toString() == 'http://localhost/p3/p2a?a=1'

   uri.path = '../p4'
   assert uri.toString() == 'http://localhost/p4?a=1&b=2&c=3#frag'

I understand this to mean that if you set the uri.path of an httpbuilder object with a slash at the end, you have essentially updated the working path so any subsequent relative path updates to uri.path will result in a concatenation of the path. Therefore, your POST in that example ends up pointing at https://myBaseURI/some/api/path/some/other/api/path