Here at BTI, some of our projects involve building Grails applications with Groovy. Groovy and Grails each have components that can make RESTful client calls easier, and in this blog post we’ll take a brief look at a few of the components that Groovy offers.
HTTPBuilder is an open-source library built on top of Groovy and Apache HttpClient and is used to manipulate HTTP-based resources. This library’s main class is the HTTPBuilder, for which the library has a subclass called RESTClient that we’ll explore. With RESTClient, we can perform the standard GET, POST, UPDATE, and DELETE method calls, as well as OPTIONS and HEAD calls (we saw this in our previous blog post on Apache HttpClient).
First, to demonstrate a GET call, we’ll instantiate a RESTClient with a sample RESTful web service URL, using the dictionary from BTI’s screencasts about Spring:
import groovyx.net.http.RESTClient
localDictionary = new RESTClient('http://localhost:8080/SpringDictionaryService/bti/dictionary/')
To perform a GET with this new object, while assuming that our dictionary returns XML by default and has the words “set” and “list” already defined, we can say
def resp = localDictionary.get(path: 'set')
assert resp.status == 200
assert resp.contentType == groovyx.net.http.ContentType.XML.toString()
println resp.data.name
println resp.data.definition
which would return the following content:
set
A collection that can only contain unique elements
The argument to this GET method is a Map with key type of String, and a value of any type (Map<String, ?>). All six of the method calls that can be performed with the RESTClient class have this single argument. The list of acceptable keys includes, among others, “path”: the URL path of the service we are calling; “contentType”: the request content type; and “body”: the contents of the request body.
Let’s take a look at another operation for adding an entry to our dictionary, using POST:
def new_word = '''<word><definition>Someone who makes everyone around them betterr.
</definition><name>ultimate teammate</name></word>'''
def resp = localDictionary.post(path : 'ultimate teammate', body : new_word,
requestContentType : groovyx.net.http.ContentType.XML)
assert resp.status == 301
With our existing Spring Dictionary Service, a subsequent GET for this word, using a web browser to access a URL with /SpringDictionaryService/bti/dictionary/ultimate%20teammate in its path will return
<word>
<definition>Someone who makes every around them betterr</definition>
<name>ultimate teammate</name>
</word>
Our response status code in our Spring dictionary service is 301, Moved Permanently, because sometimes a client will subsequently issue a GET request for the resource. In our case, with the Ext JS-based client developed for BTI’s Spring dictionary service blog posts / videos, running in Firefox, this is what occurs: a POST will be automatically followed by a GET for the same resource (“ultimate teammate” in this example). It may be equally valid to return a “201 Created” status code, as a resource has in fact been successfully created, and also because, according to the