Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the REST response in Groovy?

Tags:

rest

groovy

I have to write a small script within a web app. This web app has it's limitations but is similar to this online console: https://groovyconsole.appspot.com/ so if it works here, it should work for my problem as well.

I need to parse a JSON response. For simplicity I developed in C# my own web API and when I enter on the browser the link (http://localhost:3000/Test) it gives this string :

{"Code":1,"Message":"This is just a test"}

I want to get this string, and parse it afterwards, I guess with JsonSplunker. After hours of research, the most compelling sample would be this:

import groovyx.net.http.RESTClient

def client = new RESTClient( 'http://www.acme.com/' )
def resp = client.get( path : 'products/3322' ) // ACME boomerang

assert resp.status == 200  // HTTP response code; 404 means not found, etc.
println resp.getData()

(taken from here: http://rest.elkstein.org/2008/02/using-rest-in-groovy.html)

However it does not recognize import groovyx.net.http.RESTClient. You can try testing it in the groovy web sonsole provided and you will get the error.

I tried import groovyx.net.http.RESTClient.* but still no success.

like image 906
Liviu Sosu Avatar asked Aug 27 '16 14:08

Liviu Sosu


People also ask

What is a response in rest?

When you send a REST request, the appliance responds with a structured response in JSON format. The exact structure of the response depends on the resource and URI of the request, but all responses are similar. The response includes all available resources from any point within the API.

How do I create a groovy script?

Create a Groovy ScriptFrom the Tools Main menu select Groovy > New Script. This opens the Groovy editor. Enter the Groovy code.


3 Answers

Here is a simple Groovy script that sends an HTTP POST to an online server and parses the response with JsonSlurper.

This script can run as standalone on your machine; it probably won't work in an online Groovy REPL. It uses the Apache HTTPClient jar, which is added to the classpath via @Grab.

For a project, one would not use this method but rather add the jar to the classpath in Gradle.

like image 172
Michael Easter Avatar answered Nov 14 '22 10:11

Michael Easter


I have tried to find an existing REST client to use but I always end up creating my own. I mostly use it in Jenkins pipelines, something like this:

new RestClient(this,"http://some-server.domain/gitlab")
 .get('/api/v4/projects/' + repo.id + '/hooks')
 .each { hook ->
  println "Hook: " + hook
 }

And here is the actual RestClient:

package se.bjurr.jenkinssandbox

public class RestClient {
  private def baseUrl
  private def steps

  public RestClient(def steps, def baseUrl='http://localhost') {
    this.steps = steps
    this.baseUrl = baseUrl
  }

  def get(def path) {
    def responseText = ""
    steps.withCredentials([steps.string(credentialsId: 'gitlab-token', variable: 'gitlabToken')]) {
      steps.println "Using token: "+steps.env.gitlabToken +" to get \"" + baseUrl + path + "\""
      def conn = null
      try {
        conn = new URL(baseUrl+path).openConnection();
        conn.setRequestMethod("GET")
        conn.setRequestProperty("Content-Type", "application/json")
        conn.setRequestProperty("Private-Token", steps.env.gitlabToken)
        conn.setDoOutput(false)
        def postRC = conn.getResponseCode();
        responseText = conn.getInputStream().getText()
        steps.println "Got: " + postRC + "\n"+responseText
      } finally {
        conn.disconnect()
      }
      //Because classic is serilizable
      return new groovy.json.JsonSlurperClassic().parseText(responseText)
    }
  }

  def delete(def path) {
    def responseText = ""
    steps.withCredentials([steps.string(credentialsId: 'gitlab-token', variable: 'gitlabToken')]) {
      steps.println "Using token: "+steps.env.gitlabToken +" to delete \"" + baseUrl + path + "\""
      def conn = null
      try {
        conn = new URL(baseUrl+path).openConnection();
        conn.setRequestMethod("DELETE")
        conn.setRequestProperty("Private-Token", steps.env.gitlabToken)
        conn.setDoOutput(false)
        def postRC = conn.getResponseCode();
        responseText = conn.getInputStream().getText()
        steps.println "Got: " + postRC + "\n"+responseText
      } finally {
        conn.disconnect()
      }
    }
  }

  def post(def path) {
    def responseText = ""
    steps.withCredentials([steps.string(credentialsId: 'gitlab-token', variable: 'gitlabToken')]) {
      steps.println "Using token: "+steps.env.gitlabToken +" to post \"" + baseUrl + path + "\""
      def conn = null
      try {
        conn = new URL(baseUrl+path).openConnection();
        conn.setRequestMethod("POST")
        conn.setRequestProperty("Content-Type", "application/json")
        conn.setRequestProperty("Private-Token", steps.env.gitlabToken)
        conn.setDoOutput(false)
        def postRC = conn.getResponseCode();
        responseText = conn.getInputStream().getText()
        steps.println "Got: " + postRC + "\n"+responseText
      } finally {
        conn.disconnect()
      }
      //Because classic is serilizable
      return new groovy.json.JsonSlurperClassic().parseText(responseText)
    }
  }

  def post(def path, def payload) {
    def responseText = ""
    steps.withCredentials([steps.string(credentialsId: 'gitlab-token', variable: 'gitlabToken')]) {
      String jsonString = new groovy.json.JsonBuilder(payload).toPrettyString()
      steps.println "Using token: "+steps.env.gitlabToken +" to post \"" + baseUrl + path + "\" with:\n"+jsonString
      def conn = null
      try {
        conn = new URL(baseUrl+path).openConnection();
        conn.setRequestMethod("POST")
        conn.setRequestProperty("Content-Type", "application/json")
        conn.setRequestProperty("Private-Token", steps.env.gitlabToken)
        conn.setDoOutput(true)
        conn.getOutputStream().write(jsonString.getBytes("UTF-8"));
        def postRC = conn.getResponseCode();
        responseText = conn.getInputStream().getText()
        steps.println "Got: " + postRC + "\n"+responseText
      } finally {
        conn.disconnect()
      }
      //Because classic is serilizable
      return new groovy.json.JsonSlurperClassic().parseText(responseText)
    }
  }
}
like image 29
Tomas Bjerre Avatar answered Nov 14 '22 10:11

Tomas Bjerre


If your problem is with importing groovyx.net.http.RESTClient, then you're missing the dependency org.codehaus.groovy.modules.http-builder:http-builder.

If you're dealing with just a stand-alone Groovy script, you can use Groovy's Grape to fetch the dependency. Here's an example from RESTClient's home page:

@Grab('org.codehaus.groovy.modules.http-builder:http-builder:0.7')
@Grab('oauth.signpost:signpost-core:1.2.1.2')
@Grab('oauth.signpost:signpost-commonshttp4:1.2.1.2')

import groovyx.net.http.RESTClient
import static groovyx.net.http.ContentType.*

def twitter = new RESTClient( 'https://api.twitter.com/1.1/statuses/' )
// twitter auth omitted

try { // expect an exception from a 404 response:
    twitter.head path: 'public_timeline'
    assert false, 'Expected exception'
}
// The exception is used for flow control but has access to the response as well:
catch( ex ) { assert ex.response.status == 404 }

assert twitter.head( path: 'home_timeline.json' ).status == 200

If your web app uses a dependency system, such as Gradle, then you can use it instead of @Grab.

like image 23
Emmanuel Rosa Avatar answered Nov 14 '22 08:11

Emmanuel Rosa