I wonder how to call REST API from a (groovy) Jenkins workflow script. I can execute "sh 'curl -X POST ...'" - it works, but building the request as a curl command is cumbersome and processing the response gets complicated. I'd prefer a native Groovy HTTP Client to program in groovy - which one should I start with? As the script is run in Jenkins, there is the step of copying all needed dependency jars to the groovy installation on Jenkins, so something light-weight would be appreciated.
-
Did you find out how to install HTTPBuilder into Jenkins? – S.Richmond Jan 19 '16 at 00:26
-
S. Richmond, copying all missing jars to the Groovy libs folder, as mentioned in the question, works, but this makes provisioning of a Jenkins server too complicated. I think I am sticking to curl after all. – Assen Kolov Mar 15 '16 at 09:40
-
Would you mind pointing out to me where the folder exists within a jenkins installation? – S.Richmond Mar 15 '16 at 15:06
-
1I run Jenkins in a docker image where I have installed groovy with skdman. The lib folder is var/jenkins_home/.sdkman/candidates/groovy/2.4.6/lib. – Assen Kolov Mar 15 '16 at 16:51
6 Answers
Native Groovy Code without importing any packages:
// GET
def get = new URL("https://httpbin.org/get").openConnection();
def getRC = get.getResponseCode();
println(getRC);
if(getRC.equals(200)) {
println(get.getInputStream().getText());
}
// POST
def post = new URL("https://httpbin.org/post").openConnection();
def message = '{"message":"this is a message"}'
post.setRequestMethod("POST")
post.setDoOutput(true)
post.setRequestProperty("Content-Type", "application/json")
post.getOutputStream().write(message.getBytes("UTF-8"));
def postRC = post.getResponseCode();
println(postRC);
if(postRC.equals(200)) {
println(post.getInputStream().getText());
}

- 2,545
- 1
- 12
- 15
-
1I ended up using this as the `HTTP Request` plugin started hanging on our Windows Jenkins instance. Thanks! – Cole Jun 06 '19 at 16:43
-
URL.openConnection() may introduce security vulnerabilities and hence jenkins advice to forbid it. And if allow it, this will open this method call for other 3rd party plugin and may make it more vulnerable. – old-monk Jun 21 '19 at 15:19
-
-
There is a built in step available that is using Jenkins HTTP Request Plugin to make http requests.
Plugin: https://wiki.jenkins-ci.org/display/JENKINS/HTTP+Request+Plugin
Step documentation: https://jenkins.io/doc/pipeline/steps/http_request/#httprequest-perform-an-http-request-and-return-a-response-object
Example from the plugin github page:
def response = httpRequest "http://httpbin.org/response-headers?param1=${param1}"
println('Status: '+response.status)
println('Response: '+response.content)

- 3,875
- 5
- 26
- 37
-
does it support https? if so, how to configure certificates? @raitisd – Joey Trang Aug 02 '17 at 04:35
-
@Van, I assume you don't need to configure anything on Jenkins side. You just use https in the url and thats it. And the resource you call has to have ssl set up. – raitisd Aug 10 '17 at 08:46
-
-
-
2
-
I had trouble installing the HTTPBuilder library, so I ended up using the more basic URL class to create an HttpUrlConnection.
HttpResponse doGetHttpRequest(String requestUrl){
URL url = new URL(requestUrl);
HttpURLConnection connection = url.openConnection();
connection.setRequestMethod("GET");
//get the request
connection.connect();
//parse the response
HttpResponse resp = new HttpResponse(connection);
if(resp.isFailure()){
error("\nGET from URL: $requestUrl\n HTTP Status: $resp.statusCode\n Message: $resp.message\n Response Body: $resp.body");
}
this.printDebug("Request (GET):\n URL: $requestUrl");
this.printDebug("Response:\n HTTP Status: $resp.statusCode\n Message: $resp.message\n Response Body: $resp.body");
return resp;
}
/**
* Posts the json content to the given url and ensures a 200 or 201 status on the response.
* If a negative status is returned, an error will be raised and the pipeline will fail.
*/
HttpResponse doPostHttpRequestWithJson(String json, String requestUrl){
return doHttpRequestWithJson(json, requestUrl, "POST");
}
/**
* Posts the json content to the given url and ensures a 200 or 201 status on the response.
* If a negative status is returned, an error will be raised and the pipeline will fail.
*/
HttpResponse doPutHttpRequestWithJson(String json, String requestUrl){
return doHttpRequestWithJson(json, requestUrl, "PUT");
}
/**
* Post/Put the json content to the given url and ensures a 200 or 201 status on the response.
* If a negative status is returned, an error will be raised and the pipeline will fail.
* verb - PUT or POST
*/
HttpResponse doHttpRequestWithJson(String json, String requestUrl, String verb){
URL url = new URL(requestUrl);
HttpURLConnection connection = url.openConnection();
connection.setRequestMethod(verb);
connection.setRequestProperty("Content-Type", "application/json");
connection.doOutput = true;
//write the payload to the body of the request
def writer = new OutputStreamWriter(connection.outputStream);
writer.write(json);
writer.flush();
writer.close();
//post the request
connection.connect();
//parse the response
HttpResponse resp = new HttpResponse(connection);
if(resp.isFailure()){
error("\n$verb to URL: $requestUrl\n JSON: $json\n HTTP Status: $resp.statusCode\n Message: $resp.message\n Response Body: $resp.body");
}
this.printDebug("Request ($verb):\n URL: $requestUrl\n JSON: $json");
this.printDebug("Response:\n HTTP Status: $resp.statusCode\n Message: $resp.message\n Response Body: $resp.body");
return resp;
}
class HttpResponse {
String body;
String message;
Integer statusCode;
boolean failure = false;
public HttpResponse(HttpURLConnection connection){
this.statusCode = connection.responseCode;
this.message = connection.responseMessage;
if(statusCode == 200 || statusCode == 201){
this.body = connection.content.text;//this would fail the pipeline if there was a 400
}else{
this.failure = true;
this.body = connection.getErrorStream().text;
}
connection = null; //set connection to null for good measure, since we are done with it
}
}
And then I can do a GET with something like:
HttpResponse resp = doGetHttpRequest("http://some.url");
And a PUT with JSON data using something like:
HttpResponse resp = this.doPutHttpRequestWithJson("{\"propA\":\"foo\"}", "http://some.url");

- 1,595
- 2
- 11
- 10
-
Thank you this is probably the way to go. I upvoted your answer and will accept it once I have some time to test it. – Assen Kolov Apr 14 '16 at 18:25
-
1Thanks, this is great. I needed to add basic auth: `def auth_token = "user:github_token"; def basic_auth = "Basic ${auth_token.bytes.encodeBase64().toString()}"; connection.setRequestProperty("Authorization", basic_auth);` – J.Z. Jun 06 '18 at 23:22
Have you tried Groovy's HTTPBuilder Class? For example:
@Grapes(
@Grab(group='org.codehaus.groovy.modules.http-builder', module='http-builder', version='0.7.1')
)
import groovyx.net.http.HTTPBuilder
import static groovyx.net.http.ContentType.*
import static groovyx.net.http.Method.*
def http = new HTTPBuilder("http://api.geonames.org/citiesJSON?north=44.1&south=-9.9&east=-22.4&west=55.2&lang=de&username=demo")
http.request(POST, JSON ) { req ->
body = []
response.success = { resp, reader ->
println "$resp.statusLine Respond rec"
}
}

- 7,709
- 4
- 36
- 51
-
3As per OP's request, could you expand a little on how to install the HTTPBuilder library into Jenkins? It does not appear to be available by default. – S.Richmond Jan 19 '16 at 00:16
-
1I have updated the example to show how to use Grapes Grab to pull the dependant HttpBuilder library without the need for additional steps to include in the Jenkins classpath. – pczeus Jan 20 '16 at 18:59
-
I finally got around to testing this and unfortunately it fails with the error here: https://gist.github.com/strich/38e472eac507bc73e785 – S.Richmond Jan 31 '16 at 17:09
-
I have the same problem than S. Richmond with org.apache.ivy. @pczeus, do you have an idea how to solve this ? – Cyrille Sep 20 '16 at 13:47
-
I ran into this myself (problem with Ivy). I believe it was resolved when I wiped out the .grapes cache and did a Rebuild Project in IntelliJ, not sure. Regardless, here is 2 links that may help: http://stackoverflow.com/questions/31498714/cannot-install-httpbuilder and http://stackoverflow.com/questions/28888337/installing-httpbuilder-for-groovy/34814548?noredirect=1#comment64040038_34814548 – pczeus Sep 20 '16 at 14:56
-
Anyone managed use this? On the `@Grab` statement, I am getting `org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed: General error during conversion: Error grabbing Grapes -- [unresolved dependency: org.codehaus.groovy.modules.http-builder#http-builder;0.7: not found]`. – bsky Feb 15 '17 at 11:21
Blocking the main thread on I/O calls is not a good idea.
Delegating the I/O operation to a shell step is the recommended way currently.
The other way, which requires development, is to add a new step. By the way, there is an initiative to add a common set of steps to be used securely inside the pipeline script, although a full REST client owes its own plugin.

- 3,292
- 2
- 20
- 22
Do a GET with the Basic Auth header.
def accessToken = "ACCESS_TOKEN".bytes.encodeBase64().toString()
def req = new URL("https://raw.githubusercontent.com/xxxx/something/hosts").openConnection();
req.setRequestProperty("Authorization", "Basic " + accessToken)
def content = req.getInputStream().getText()

- 12,828
- 2
- 25
- 45