Calling RESTful Services with Groovy

September 26, 2014 in Java Articles

Written by Ken Kousen


(or The Reason the Internet Was Invented, or Cat Pictures for the Win)

In this article, I’ll use Groovy to access a publicly available RESTful web service, parse the downloaded data, and build a GUI to hold the resulting images. The code will demonstrate the Groovy JDK, maps, the collect method, I/O processing, and the builder pattern, all to achieve its ultimate goal: looking at cat pictures.

A Flickering Light In The Darkness

There are many so-called RESTful web services available to the general public. Despite the name, however, most only support GET requests. This isn’t terribly surprising, since POST, PUT, and DELETE would require some kind of transaction, and security, and all sorts of protection against the sort of damage reminiscent of YouTube comments[1].

Examples of that sort of services include Open Weather Map (http://openweathermap.org/api), Currency Exchange Rates (http://openexchangerates.org), the Bing[2] Maps REST services (http://msdn.microsoft.com/en-us/library/ff701713.aspx), the Google Maps Geocoder (https://developers.google.com/maps/documentation/geocoding/) and the source for this article, Flickr (https://secure.flickr.com/services/developer). Each supports HTTP GET requests only.

NOTE If a RESTful web service only supports GET requests, does that make it a GETful service? If so, and it’s also stateless, does that make it a FORGETful web service? Thank you, thank you. Try the veal, and please remember to tip your wait staff.

 

Believe it or not, Flickr used to be the definitive site for image sharing, and some people still use it. Access requires a key, which means you need to register with Yahoo!, another web site that used to matter long, long ago when the web was shiny and new.

Why use it here? It’s available, it’s free, and, most important of all, it’s got cat pictures.

Feeling Groovy

Groovy is one of the new family of languages that compiles to bytecodes for the Java Virtual Machine. It’s simpler than Java, yet much more powerful, and has an easy learning curve for existing Java developers. It’s cool in its own right, and also forms the basis of interesting projects like Grails and Gradle.

Hey, I even wrote a Java/Groovy integration book about it.

Now on to the Groovy. Let’s assume you register and receive your special key. Save it in a file called flickr_key.txt, so you can access it this way:

String key = new File('flickr_key.txt').text

Accessing a property (like text here) in Groovy is the same as invoking the corresponding getter or setter method. Here, the Groovy JDK adds the getText method to File, which returns the contents of the file.

The base URL for the web service is:

String endPoint = 'https://api.flickr.com/services/rest?'

I included the “?” because I want to append the generated query string to the end point to get the complete URL.

The Flickr API uses a query string with a lot of parameters. Here I add them to a Groovy map.

def params = [method: 'flickr.photos.search', api_key: key,
    format: 'json', tags: 'cat', nojsoncallback: 1,
    media: 'photos', per_page: 6]

I’m calling the flickr.photos.search method with the api_key. I want JSON data back, but not as a JSON callback, and I want photo data using the cat tag. It’s not terribly complicated, but there are a lot of parameters.

The cool part is that a Groovy map like this can be converted to a query string using a very common idiom. Thecollect method applied to a map generates a list by applying a closure to each element of the original list. Therefore I can generate the query string thusly:

def qs = params.collect { k,v -> "$k=$v" }.join('&')

The two-argument closure takes each key/value pair and returns a string where the key equals the value. Then thejoin method applied to the list creates a string whose entries are separated by ampersands.

That means the whole URL is defined by "$endPoint$qs". I can then use the toURL method from the Groovy JDK to convert the string to a URL[3], and the text parameter invokes getText, returning the total response.

I can now use the cool JsonOutput.prettyPrint(txt) method to format the output and write it to a file.

File f = new File('cats.json')
if (f) f.delete()
f << jsonTxt
println JsonOutput.prettyPrint(jsonTxt)

Here’s a sample from that output.

{
    "photos": {
        "page": 1,
        "pages": 882777,
        "perpage": 6,
        "total": "5296661",
        "photo": [
            {
                "id": "15077663928",
                "owner": "[email protected]",
                "secret": "dc605f2671",
                "server": "3837",
                "farm": 4,
                "title": "Mornings with bb kitty",
                "ispublic": 1,
                "isfriend": 0,
                "isfamily": 0
            },
            { ... },
            { ... },
            { ... },
            { ... },
            { ... }
        ]
    },
    "stat": "ok"
}

From JSON to Cat Pictures

Each photo block has the components necessary to assemble the URL to retrieve it, which is way more complicated than it needs to be but is still doable. Here’s the code for that part.

def json = new JsonSlurper().parseText(jsonTxt)
def urls = json.photos.photo.collect { p ->
    "http://farm${p.farm}.staticflickr.com/${p.server}/${p.id}_${p.secret}.jpg"
}

The JsonSlurper has a parseText method that converts the received JSON string into a Groovy map. Then walking the map by calling json.photos.photo gets all the photo objects, and the collect block converts each of them into a URL.

All that remains is to access all the photo URLs and populate a simple GUI with them. One simple way to do that is to use Groovy’s SwingBuilder class.

new SwingBuilder().edt {
    frame(title:'Cat pictures', visible: true, pack: true,
        defaultCloseOperation: WindowConstants.EXIT_ON_CLOSE,
        layout:new GridLayout(0, 2)) {
        urls[0..5].each { String url ->
            label(icon:new ImageIcon(url.toURL()))
        }
    }
}

The SwingBuilder has an edt method, which builds the UI on the event dispatch thread. The frame “method” instantiates a JFrame with the given title, makes it visible, and packs it as small as possible. The GUI uses aGridLayout to make two columns of equally-spaced elements, each of which is a JLabel that contains an ImageIconwith the individual photo URLs.

The result is a display of the most recent six pictures tagged cat in Flickr, which can result in almost anything[4].

Here’s a sample view:

Cat Pictures

NOTE Don’t ask me about the monkey. I have no idea what that’s about either.

 

So what have we learned?

  1. Groovy maps can be converted to query strings using a closure and the join method
  2. The Groovy JDK adds methods to Java library classes that you wished were there all along
  3. Groovy builders can make Swing programming almost, but not quite, pretty cool
  4. I can haz kitteh pics

The entire script from this article is part of a GitHub repository called IntroGroovy. You’ll need to add your own Flickr key, but after that, go for it. Just don’t be surprised, apparently, if you get monkeys or tractors mixed in with your cat pictures.

I suppose now I should go and re-implement the whole thing in <a href=”http://lolcode.org”>LOLCODE</a>.


1. Okay, that’s a little harsh. Nothing could be as awful as YouTube comments. Or perhaps the correct response to that is, “I didn’t know YouTube supported comments.” If that’s your answer, I SO wish I was you.

2. Come on, stop laughing. I get it: “if you don’t remember what Bing is, just Google it”. Ha ha.

3. What did you expect toURL to convert the string into, a tomato? That would be pretty cool, actually. Now I wish I had that method. Of course, Groovy is an open source project…?

4. Usually it’s cats, but once I got a bunch of tractors, which confused me until I realized they were manufactured by Caterpillar.

 

Respectfully submitted by Ken Kousen <[email protected]>, who teaches this stuff

Accelebrate offers private Groovy training for groups.


Written by Ken Kousen

Ken Kousen

Ken Kousen is an independent consultant and trainer specializing in Spring, Hibernate, Groovy, and Grails. He is a regular speaker at conferences and the Author of "Modern Java Recipes" (O'Reilly Media), "Gradle Recipes for Android" (O'Reilly Media), and "Making Java Groovy" (Manning).
  



Contact Us:

Accelebrate’s training classes are available for private groups of 3 or more people at your site or online anywhere worldwide.

Don't settle for a "one size fits all" public class! Have Accelebrate deliver exactly the training you want, privately at your site or online, for less than the cost of a public class.

For pricing and to learn more, please contact us.

Contact Us Train For Us

Toll-free in US/Canada:
877 849 1850
International:
+1 678 648 3113

Toll-free in US/Canada:
866 566 1228
International:
+1 404 420 2491

925B Peachtree Street, NE
PMB 378
Atlanta, GA 30309-3918
USA

Subscribe to our Newsletter:

Never miss the latest news and information from Accelebrate:

Microsoft Gold Partner

Please see our complete list of
Microsoft Official Courses

Recent Training Locations

Alabama

Huntsville

Montgomery

Birmingham

Alaska

Anchorage

Arizona

Phoenix

Tucson

Arkansas

Fayetteville

Little Rock

California

San Francisco

Oakland

San Jose

Orange County

Los Angeles

Sacramento

San Diego

Colorado

Denver

Boulder

Colorado Springs

Connecticut

Hartford

DC

Washington

Florida

Fort Lauderdale

Miami

Jacksonville

Orlando

Saint Petersburg

Tampa

Georgia

Atlanta

Augusta

Savannah

Idaho

Boise

Illinois

Chicago

Indiana

Indianapolis

Iowa

Ceder Rapids

Des Moines

Kansas

Wichita

Kentucky

Lexington

Louisville

Louisiana

Banton Rouge

New Orleans

Maine

Portland

Maryland

Annapolis

Baltimore

Hagerstown

Frederick

Massachusetts

Springfield

Boston

Cambridge

Michigan

Ann Arbor

Detroit

Grand Rapids

Minnesota

Saint Paul

Minneapolis

Mississippi

Jackson

Missouri

Kansas City

St. Louis

Nebraska

Lincoln

Omaha

Nevada

Reno

Las Vegas

New Jersey

Princeton

New Mexico

Albuquerque

New York

Buffalo

Albany

White Plains

New York City

North Carolina

Charlotte

Durham

Raleigh

Ohio

Canton

Akron

Cincinnati

Cleveland

Columbus

Dayton

Oklahoma

Tulsa

Oklahoma City

Oregon

Portland

Pennsylvania

Pittsburgh

Philadelphia

Rhode Island

Providence

South Carolina

Columbia

Charleston

Spartanburg

Greenville

Tennessee

Memphis

Nashville

Knoxville

Texas

Dallas

El Paso

Houston

San Antonio

Austin

Utah

Salt Lake City

Virginia

Richmond

Alexandria

Arlington

Washington

Tacoma

Seattle

West Virginia

Charleston

Wisconsin

Madison

Milwaukee

Alberta

Edmonton

Calgary

British Columbia

Vancouver

Nova Scotia

Halifax

Ontario

Ottawa

Toronto

Quebec

Montreal

Puerto Rico

San Juan

© 2013-2019 Accelebrate, Inc. All Rights Reserved. All trademarks are owned by their respective owners.