36

Hi I need to call a REST service as part of the buildscript (Gradle) without any 3rd party plugins, how could I use Groovy to do that?

(My first attempt)

repositories {
    mavenCentral()
}
      dependencies {  
            complie "org.codehaus.groovy.modules.http-builder:http-builder:0.5.2"  
    }  

task hello {
    def http = new HTTPBuilder("http://myserver.com:8983/solr/select?q=*&wt=json")
    http.auth.basic 'username', 'password'
    http.request(GET, JSON ) { req ->
    }
}
Bostone
  • 36,858
  • 39
  • 167
  • 227
user2599381
  • 727
  • 1
  • 8
  • 16
  • What method are you calling? If it's GET, it's easy ;-) – tim_yates Jun 05 '14 at 11:35
  • Yes It is a getdose this code any where near what I want to do? 'repositories { mavenCentral() } dependencies { complie "org.codehaus.groovy.modules.http-builder:http-builder:0.5.2" } task hello { def http = new HTTPBuilder("http://localhost:8983/solr/select?q=*&wt=json") http.auth.basic 'username', 'password' http.request(GET, JSON ) { req -> } }' – user2599381 Jun 05 '14 at 11:42

7 Answers7

29

Can't you just do

new URL( 'http://username:password@myserver.com:8983/solr/select?q=*&wt=json' ).text
tim_yates
  • 167,322
  • 27
  • 342
  • 338
  • 3
    The question was about general REST, not particularly GET, so I guess curl is more suitable for that. – JBaruch Jun 06 '14 at 21:57
  • Is there a way to add encoding/charset to this kind of request? – user1354603 Feb 28 '17 at 16:24
  • 1
    See my answer (currently the newest one, but at the very bottom) for using the Java standard lib http client (usable unless you're still stuck on Java 8). With that you can do anything. – Renato Sep 29 '22 at 09:07
18

this is working guys

import java.io.*
import groovyx.net.http.HTTPBuilder
import groovyx.net.http.EncoderRegistry
import static groovyx.net.http.Method.*
import static groovyx.net.http.ContentType.*

buildscript {
    repositories {
        mavenCentral()
    }   
    dependencies {
        classpath 'org.codehaus.groovy.modules.http-builder:http-builder:0.5.2'
    }   
}

task hello {
    def http = new groovyx.net.http.HTTPBuilder("http://local.com:8983/solr/update/json")

    http.request(POST, JSON ) { req ->
        req.body{

        }
        response.success = { resp, reader ->
            println "$resp.statusLine   Respond rec"

        }
    }
}
Chris Snow
  • 23,813
  • 35
  • 144
  • 309
user2599381
  • 727
  • 1
  • 8
  • 16
  • 3
    Didn't you want to do it without 3rd-party tools and simple? Compare the amount of code in your answer and mine. – JBaruch Jun 05 '14 at 13:20
  • 1
    I could get your code to work so I wrote this, trust me not proud of it, could you be kind enough to give a full code example with all the imports? Thanks for your help – user2599381 Jun 05 '14 at 15:35
  • where can i see other examples, for example, how to do get request with headers? also build.dependsOn =['hello'] should print me smth on terminal shouldn't it?cause it is not right now – Nazerke Sep 04 '16 at 08:07
  • 6
    i added a plus one for not needing curl – Nicholas DiPiazza Jun 19 '17 at 07:37
16

This question is ranking so well on search engines that I keep stumbling on it.

However, as others commented, I don't really like the accepted answer because it relies on curl.

So here is a complete example w/o any prerequisite (no plugin, no curl, ...):

import groovy.json.JsonSlurper
import groovy.json.JsonOutput
task getExample {
    doLast {
        def req = new URL('https://jsonplaceholder.typicode.com/posts/1').openConnection()
        logger.quiet "Status code: ${req.getResponseCode()}"
        def resp = new JsonSlurper().parseText(req.getInputStream().getText())
        logger.quiet "Response: ${resp}"
    }
}
task postExample {
    doLast {
        def body = [title: "foo", body: "bar", userId: 1]
        def req = new URL('https://jsonplaceholder.typicode.com/posts').openConnection()
        req.setRequestMethod("POST")
        req.setRequestProperty("Content-Type", "application/json; charset=UTF-8")
        req.setDoOutput(true)
        req.getOutputStream().write(JsonOutput.toJson(body).getBytes("UTF-8"))
        logger.quiet "Status code: ${req.getResponseCode()}" // HTTP request done on first read
        def resp = new JsonSlurper().parseText(req.getInputStream().getText())
        logger.quiet "Response: ${resp}"
    }
}

You can run this on your box as they use a public development API.

Yann Vo
  • 1,793
  • 1
  • 15
  • 10
  • Someone suggest ```org.jetbrains.kotlin.js.parser.sourcemaps.parseJson``` for ```build.gradle.kts```. Migration to kotlin dsl is recommended and seems to become mandatory since Android Studio Giraffe – Gleichmut Jul 03 '23 at 15:04
10

The easiest way to call REST from groovy without external libraries is executing CURL. Here's an example of calling Artifactory, getting JSON back and parsing it:

import groovy.json.JsonSlurper

task hello {
    def p = ['curl', '-u', '"admin:password"', "\"http://localhost:8081/api/storage/libs-release-local?list&deep=1\""].execute()
    def json = new JsonSlurper().parseText(p.text)
}
Mike
  • 10,297
  • 2
  • 21
  • 21
JBaruch
  • 22,610
  • 5
  • 62
  • 90
  • 52
    This solution is system dependent. – Opal Jun 05 '14 at 11:53
  • 4
    @Opal As long as it covers Linux, MacOs and Windows, I am OK with that. – JBaruch Jun 05 '14 at 13:11
  • There is curl for Windows? – Opal Jun 05 '14 at 13:15
  • 2
    Haven't known that. Thanks! – Opal Jun 05 '14 at 13:28
  • 22
    -1, you avoided external libraries by using an external tool (CURL). Gradle is all setup to download and install libraries automatically, but it won't do the same for CURL. – Iain Sep 17 '15 at 05:59
  • 6
    That's not the [Code Golf](http://codegolf.stackexchange.com/), and not a programming Olympics. My solution gets the work done in the simplest possible way, specially considering lack of good Groovy libraries for REST API (HttpBuilder is not that great). – JBaruch Sep 17 '15 at 06:31
  • 2
    @JBaruch it's not Olympics, but still this solution doesn't work. It does NOT work on Windows, does NOT work on many Linux distributions (including ones commonly used for docker containers). It just pushes the setup problem from Gradle to operating system. – fdreger May 02 '17 at 07:01
  • @fdreger That was a long time ago, before Docker. Today I'd use [HTTP Builder NG](http://http-builder-ng.github.io/http-builder-ng) provided by [Grape](http://docs.groovy-lang.org/latest/html/documentation/grape.html) – JBaruch May 02 '17 at 08:36
  • 2
    @JBaruch Yes, exactly as I said: your solution is barely three years old, and already so bad, that even you, its author wouldn't use it today. Some other answers (including the ones that you commented on and described as inferior) still make a lot of sense (and read your own comments again in the light of using HTTP Builder NG today). – fdreger May 08 '17 at 14:23
  • @fdreger not sure what your point is, that my solution didn't answer the requirement in the question 3 years ago, or that is is obsolete now? Or maybe you think that it's wrong because it wasn't forward compatible 3 years ago and you expected me to predict what happens in 3 years? – JBaruch May 08 '17 at 18:36
  • 11
    @JBaruch no special point and no personal offence. But I noted that 1) you gave a sloppy answer that didn't meet the requirements; 2) then you took time to personally criticize other answers and gloat that yours is better; 3) you didn't see the obvious flaw, which was reintroducing a problem that gradle aims to solve 4) and when it was mentioned by Iain, you ridiculed him/her by using reductio ad absurdum. So I gave a -1 as a warning for anyone who follows the route (that as you now know leads nowhere), and a short comment - because I don't like downvoting without giving reason. – fdreger May 08 '17 at 18:59
  • @fdreger you miss that three years ago the downside of my answer did not exist. CURL was there on all the major problems, which covered exactly the requirements of the question. – JBaruch May 08 '17 at 21:38
  • @LoungeKatt That depends whether you consider Windows computers operable ;) it's quite recent that they started shipping with curl. – Iain Apr 16 '18 at 03:31
  • @LoungeKatt, sigh. The questioner says they won't even install groovy libs. My comment was from September pre the Windows change. OK, I'm done. – Iain Apr 16 '18 at 08:41
  • @Iain If your comment is obsolete, you can always delete it. No need to get mad at someone else because a platform has changed over time. – Abandoned Cart Apr 16 '18 at 09:07
6

I'm using the JsonSlurper it looks quite simple and OS independent:

import groovy.json.JsonSlurper

String url = "http://<SONAR_URL>/api/qualitygates/project_status?projectKey=first"
def json = new JsonSlurper().parseText(url.toURL().text)
print json['projectStatus']['status']
Bostone
  • 36,858
  • 39
  • 167
  • 227
Zsolt
  • 1,464
  • 13
  • 22
  • 2
    This answer misses the question for the same reason as the one above. Also the JsonSlurper has next to nothing to do with the question. – Thomas Hirsch Feb 09 '17 at 16:08
  • 1
    This answer seems fine to me. The `url.toURL().text` does an HTTP GET without any new repo or import dependencies. And the OP did say they wanted to "call a REST service" which implies JSON. – MarkHu Mar 23 '18 at 20:21
  • @ThomasHirsch You should probably link to the answer, as voting tends to relocate them. https://stackoverflow.com/a/24059370/461982 – Abandoned Cart Apr 04 '18 at 06:18
3

Java has had a proper HTTP Client in the standard library since Java 9.

Here's how you can use that from a Gradle script (Groovy):

import groovy.json.JsonSlurper

import java.net.http.*
import static java.nio.charset.StandardCharsets.UTF_8

tasks.register('hello') {
    def url = new URL("http://myserver.com:8983/solr/select?q=*&wt=json")
    def req = HttpRequest.newBuilder(url.toURI()).GET().build()
    def res = HttpClient.newHttpClient()
       .send(req, HttpResponse.BodyHandlers.ofString(UTF_8))
    def parsedJson = new JsonSlurper().parseText(res.body())
    println parsedJson
}
Renato
  • 12,940
  • 3
  • 54
  • 85
1

The solution using Kotlin DSL and Fuel HTTP Client:

import com.github.kittinunf.fuel.httpPost
import com.github.kittinunf.result.Result

buildscript {
    dependencies {
        "classpath"("com.github.kittinunf.fuel:fuel:2.3.1")
    }
}

tasks {
    register("post") {
        val (request, response, result) = "https://httpbin.org/post".httpPost().responseString()
        if (result is Result.Success) {
            println(result.get())
        }
    }
}
Nolequen
  • 3,032
  • 6
  • 36
  • 55