Thursday, July 25, 2013

Groovy RESTClient, headers and authentication

I recently wanted to write some REST API calls with groovy and was using groovyx.net.http.RESTClient that is part of the HTTP Builder library (http://groovy.codehaus.org/modules/http-builder/doc/rest.html). There's not a ton of documentation on it and I was struggling to find out how to do basic authentication with it, as well as how to set headers. I finally tracked some code down on the groovy mailing list and I thought I'd detail how to do it here to help anyone else who may be looking for direct instructions how to do it. I will use the basecamp API (https://github.com/37signals/bcx-api) as an example since that's the API I was writing against (https://github.com/37signals/bcx-api). The authentication is passed by simply setting restClientInstance.auth.basic with your username and password, e.g.
def restClient = new RESTClient(...)
restClient.auth.basic "me", "password"
Headers can be set in 2 ways: by passing a map of headers when running a request, e.g.
def restClient = new RESTClient(...)
def response = restClient.get(
                   path: "projects.json",
                   headers: ["User-Agent": "My basecamp application (myemail@domain.com)"]
                )
And if you want to set a header to use on every request to the REST service, you can set default headers on the RESTClient instance, e.g.
def restClient = new RESTClient(...)
restClient.defaultRequestHeaders.'User-Agent' = "My basecamp application (myemail@domain.com)"
def response = restClient.get(path: "projects.json")
Here is a full script demonstrating how to call the projects endpoint on the basecamp api using RESTClient:
#! /usr/bin/env groovy

@Grab(group='org.codehaus.groovy.modules.http-builder', module='http-builder', version='0.5.2' )

import static groovyx.net.http.ContentType.JSON

import groovyx.net.http.RESTClient
import groovy.util.slurpersupport.GPathResult
import static groovyx.net.http.ContentType.URLENC


def accountId = "yourAccountId" // this is the number after http://basecamp.com when logged into the basecamp website e.g. http://basecamp.com/1234567
def userName = "basecampUserName"
def password = "basecampPassword"

def basecamp = new RESTClient( "https://basecamp.com/${accountId}/api/v1/".toString() )
basecamp.auth.basic userName, password

def response = basecamp.get(
                   path: "projects.json",
                   headers: ["User-Agent": "My basecamp application (myemail@domain.com)"]
                )
println response.data.toString(2)

Wednesday, February 27, 2013

Symbolic links in Windows 7

This is just a quick note on how to create symbolic directory links in Windows 7. I like to use this for development languages/frameworks (e.g. groovy, grails) so that I can easily change the version of the language that I'm using. For example, I'll have the following setup C:\dev\lang\groovy C:\dev\lang\groovy\groovy-2.0.0 C:\dev\lang\groovy\groovy-2.1.1 C:\dev\lang\groovy\groovy-latest Where groovy-latest is a symlink to the version of groovy I want to use. I found the full directions on how to create a symbolic link in Windows here: http://www.howtogeek.com/howto/16226/complete-guide-to-symbolic-links-symlinks-on-windows-or-linux/ Here is the quick version using my above example. The command for making symlinks is called "mklink":
cd c:\dev\lang\groovy
mklink /D  groovy-latest groovy-2.1.1
The /D flag indicates this is a directory link. If the link exists already you have to remove it first:
cd c:\dev\lang\groovy
rmdir groovy-latest
mklink /D  groovy-latest groovy-2.1.1

Friday, February 22, 2013

Grails pretty print using deep JSON Converter

Here's a simple little Grails code sample to enable pretty printing on your JSON Converter when using the deep option:
def index() {
    def all = Product.list()
    withFormat {
        json {
            JSON.use("deep"){
                def c = all as JSON
                c.prettyPrint = true
                render c
            }
        }
        xml {
            XML.use("deep"){  
                render all as XML 
            }
        }
    }
}
After figuring this out I also discovered the JSON View extension for Chrome, which negated my need for pretty printing JSON.