ZetCode

Groovy HTTP and REST Calls

last modified October 15, 2026

Scripts often need to call web services: fetch JSON from a REST API, send data to a server, or check whether a site responds. Groovy makes this easy because it adds helpers to the standard Java networking classes. In this tutorial, we make HTTP requests with URL.text and with HttpURLConnection for full control over headers, methods, and status codes. The examples use the public test API at jsonplaceholder.typicode.com, which accepts requests without an API key.

Reading a URL with URL.text

The simplest way to fetch a resource is the text property of a URL. Groovy opens the connection, reads the response body with the default encoding, and returns it as a string.

UrlText.groovy
def url = new URL('https://jsonplaceholder.typicode.com/todos/1')
println url.text

The URL points to a to-do item. url.text performs an HTTP GET and returns the JSON body, which the script prints unchanged.

$ groovy UrlText.groovy
{
  "userId": 1,
  "id": 1,
  "title": "delectus aut autem",
  "completed": false
}

Timeouts and Headers with getText

URL.text has no timeouts and no way to set headers. The getText method accepts a map with these options, and is the better choice for scripts that call remote servers:

UrlGetText.groovy
def url = new URL('https://jsonplaceholder.typicode.com/todos/3')
def timed = url.getText(connectTimeout: 5000, readTimeout: 5000,
        requestProperties: ['Accept': 'application/json'])
println timed.contains('"id": 3')

try {
    new URL('https://jsonplaceholder.typicode.com/todos/99999').text
} catch (FileNotFoundException e) {
    println "FileNotFoundException: ${e.message}"
}

connectTimeout and readTimeout are given in milliseconds. Without them, a stalled server can block the script for a long time. requestProperties adds HTTP headers.

new URL('https://jsonplaceholder.typicode.com/todos/99999').text

When the server answers with an error status such as 404, reading the body with text throws an exception. For a 404, Java throws FileNotFoundException, which is a known quirk of HttpURLConnection; other error codes usually produce an IOException instead.

$ groovy UrlGetText.groovy
true
FileNotFoundException: https://jsonplaceholder.typicode.com/todos/99999

GET Requests with HttpURLConnection

HttpURLConnection is the standard Java class for HTTP. It lets us set the method, read the status code and response headers, and handle errors ourselves. Groovy's openConnection method returns it from a URL.

HttpGet.groovy
import groovy.json.JsonSlurper

def conn = new URL('https://jsonplaceholder.typicode.com/todos/1').openConnection()
conn.requestMethod = 'GET'
conn.setRequestProperty('Accept', 'application/json')
conn.connectTimeout = 5000
conn.readTimeout = 5000

println "Status: ${conn.responseCode}"
println "Type: ${conn.contentType}"

def body = conn.inputStream.withReader('UTF-8') { it.text }
def todo = new JsonSlurper().parseText(body)
println "${todo.id}: ${todo.title} (done=${todo.completed})"
conn.disconnect()

The requestMethod, request headers, and timeouts are set as properties of the connection. Reading responseCode sends the request and returns the HTTP status. JsonSlurper parses the body into maps and lists, as shown in the Groovy JsonSlurper tutorial.

def body = conn.inputStream.withReader('UTF-8') { it.text }

withReader opens the stream, passes a reader to the closure, and closes the stream when the closure returns. Specifying the encoding avoids depending on the platform default.

$ groovy HttpGet.groovy
Status: 200
Type: application/json; charset=utf-8
1: delectus aut autem (done=false)

POST Requests with a JSON Body

To send data, set doOutput to true, write the body to outputStream, and then read the response. Groovy's JsonOutput converts a map to a JSON string.

HttpPost.groovy
import groovy.json.JsonOutput

def conn = new URL('https://jsonplaceholder.typicode.com/posts').openConnection()
conn.requestMethod = 'POST'
conn.doOutput = true
conn.setRequestProperty('Content-Type', 'application/json; charset=UTF-8')

def payload = JsonOutput.toJson([title: 'Hello', body: 'From Groovy', userId: 7])
conn.outputStream.withWriter('UTF-8') { it.write(payload) }

println "Status: ${conn.responseCode}"
println conn.inputStream.withReader('UTF-8') { it.text }

requestMethod = 'POST' sets the HTTP method, and doOutput = true allows the script to write a request body. The Content-Type header tells the server that the body is JSON.

The server responds with status 201 Created and returns the new resource, including an id assigned by the server.

$ groovy HttpPost.groovy
Status: 201
{
  "title": "Hello",
  "body": "From Groovy",
  "userId": 7,
  "id": 101
}

Handling Error Status Codes

A 404 or 500 response is not a network failure, so the connection works, but conn.inputStream throws for these codes. To read the error body, check the status first and use errorStream when it is 400 or higher.

HttpStatus.groovy
def conn = new URL('https://jsonplaceholder.typicode.com/todos/99999').openConnection()
conn.connectTimeout = 5000
conn.readTimeout = 5000

def code = conn.responseCode
println "Status: $code"

def stream = code >= 400 ? conn.errorStream : conn.inputStream
def text = stream?.withReader('UTF-8') { it.text } ?: ''
println "Body: '${text}'"

The script reads the status code once, then picks the right stream. The ?. and ?: operators handle a missing stream: the errorStream can be null when the server sends no body.

Each stream can be read only once. Calling .text a second time on the same stream fails with stream is closed, so store the text in a variable if you need it twice.

$ groovy HttpStatus.groovy
Status: 404
Body: '{}'

Best Practices

Source

Groovy documentation

This tutorial showed how to read URLs with URL.text and getText, send GET and POST requests with HttpURLConnection, and handle error status codes.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than eight years of experience in teaching programming.

List all Groovy tutorials.