Over a million developers have joined DZone.

Ratpacked: Use TestHttpClient for External HTTP Services

DZone's Guide to

Ratpacked: Use TestHttpClient for External HTTP Services

In this article, we learn how to leverage Ratpack's TestHttpClient to test external HTTP services, by way of example.

· Integration Zone ·
Free Resource

WSO2 is the only open source vendor to be named a leader in The Forrester Wave™: API Management Solutions, Q4 2018 Report. Download the report now or try out our product for free.

Ratpack has a very useful class: TestHttpClient. This is a blocking HTTP client that we normally use for testing our Ratpack applications. For example, we use MainClassApplicationUnderTest or GroovyRatpackMainApplicationUnderTest in a test and invoke the getHttpClient method to get an instance of TestHttpClient. The class has a lot of useful methods to make HTTP requests with a nice DSL. TestHttpClient is also very useful as a standalone HTTP client in other applications.

Suppose we have a piece of code that needs to access MapQuest Open Platform Web Services to get location details for a given combination of longitude and latitude values. In the constructor we create an instance of the interface ApplicationUnderTest. We then can use the getHttpClient method of ApplicationUnderTest to get a TestHttpClient instance:

// File: src/main/groovy/mrhaki/geocode/GeocodeService.groovy
package mrhaki.geocode

import groovy.json.JsonSlurper
import ratpack.http.client.ReceivedResponse
import ratpack.test.ApplicationUnderTest
import ratpack.test.http.TestHttpClient

class GeocodeService {

    private final ApplicationUnderTest mapQuestApi
    private final GeocodeConfig config

    GeocodeService(final GeocodeConfig config) {
        this.config = config

        // Create ApplicationUnderTest using a Closure,
        // which returns the URI of our external HTTP service.
        // The ApplicationUnderTest interface only 
        // has one method (URI getAddress()), 
        // so we can use a Closure to implement the interface.
        mapQuestApi = { config.uri.toURI() }

    Location getLocation(final Double latitude, final Double longitude) {
        // Create a blocking HttpClient with the base
        // URI from ApplicationUnderTest.
        final TestHttpClient httpClient = mapQuestApi.httpClient

        // Request location details for given latitude and longitude
        // and set the application key.
        httpClient.params { paramBuilder ->
            paramBuilder.put 'key', config.apiKey
            paramBuilder.put 'location', [latitude, longitude].join(',')

        // Use get method to get a response from the HTTP service.
        final ReceivedResponse response = httpClient.get('geocoding/v1/reverse') 

        // Transform JSON result and
        // find location specific details in the response.
        final jsonResponse = new JsonSlurper().parseText(response.body.text)
        final location = jsonResponse.results[0].locations[0]

        // Create new Location object.
        new Location(street: location.street, city: location.adminArea5)


The host name and key we need to make a request are set via the GeocodeConfig class:

// File: src/main/groovy/mrhaki/geocode/GeocodeConfig.groovy
package mrhaki.geocode

class GeocodeConfig {
    String apiKey
    String uri

And finally a simple POGO to store the location details:

// File: src/main/groovy/mrhaki/geocode/Location.groovy
package mrhaki.geocode

import groovy.transform.Immutable

class Location {
    String street
    String city

In our project we only have to add a dependency on io.ratpack:ratpack-test:

// File: build.gradle
dependencies {
    compile group: 'io.ratpack', name: 'ratpack-test', version: '1.3.3'

Written with Ratpack 1.3.3.

IAM is now more than a security project. It’s an enabler for an integration agile enterprise. If you’re currently evaluating an identity solution or exploring IAM, join this webinar.

ratpack ,http ,testing ,groovy ,external ,services ,example

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}