Wednesday, June 4th, 2008

Building RESTful Web Apps with Groovy and Restlet, Part 1: Up and Running

By Avi Flax

Here at Arc90, we love REST. We’ve implemented RESTful web apps using ColdFusion, Java, .NET/C#, and PHP. We’re big fans of Restlet, a Java REST framework. I’ve also recently started experimenting with Groovy, “an agile dynamic language for the Java Platform,” and so far I’m liking it.

So it’s a no-brainer for us to put Groovy and Restlet together and see what happens. So far, I like what I see. That said, it’ll be tough to convince some of my PHP-loving and Pythonistic colleagues to even consider Groovy, given its Java roots. Some of them fairly shudder when they hear those two syllables “ja-va”. Ooh, scary.

This blog series will be my attempt to present how Groovy and Restlet together create a compelling platform for rapid RESTful web application development.

So let’s get started with the classic Hello world!

Prerequisites

Before we get started, two prerequisites:

  1. Java 1.5 or newer – download (I used 1.5.0_13)
  2. Groovy 1.5 or newer – download (I used 1.5.6)

Setup

  1. Download the latest version of Restlet 1.1 – link – and extract it anywhere
  2. Create a folder named restfulapp
  3. Create a file named restfulapp.groovy
  4. Copy two files from the Restlet distribution’s lib folder to restfulapp:
    • org.restlet.jar
    • com.noelios.restlet.jar

I’m specifying Restlet 1.1, which hasn’t yet hit final release, as opposed to the stable 1.0 branch, because it has a built-in HTTP server and client, which makes it really easy to just dive right into development and have something up and running quickly. These built in HTTP components aren’t production-class, but they’re very convenient for our purposes here.

The Code

Before we get into the code, please note: this code does not demonstrate best practices, and is not production ready; at this point I just want to establish basic concepts.

restfulapp.groovy

Copy the following code into restfulapp.groovy:

#!/usr/bin/env groovy -classpath org.restlet.jar:com.noelios.restlet.jar
import org.restlet.*
import org.restlet.data.*
// RequestHandler will handle all of our requests
class RequestHandler extends Restlet
{
// handle() is called by the framework whenever there's a HTTP request
def void handle(Request request, Response response)
{
/* The only method that's allowed is GET, so check it -- if it's GET,
return a representation, and the default status will be returned,
which is 200 OK. If not, set the response status to an error. */
if (request.method == Method.GET)
{
/* handle() returns void, for reasons that will become clear
later. The way to output content is modify the passed-in response
by setting the Entity of the response. Restlet refers to the
Representation as an "entity"; I'm actually not 100% sure why. */
response.setEntity("Hello, world!", MediaType.TEXT_PLAIN)
}
else
{
// The request method is not GET, so set an error response status
response.setStatus(Status.CLIENT_ERROR_METHOD_NOT_ALLOWED)
response.setAllowedMethods([Method.GET] as Set)
}
}
}
/* Create a new HTTP Server on port 3000, pass it a new instance of RequestHandler,
to which it will pass all incoming Requests, and start it. */
new Server(Protocol.HTTP, 3000, new RequestHandler()).start()

I’m hoping this code illustrates some of the great aspects of Restlet and Groovy. Restlet’s class model is clear and intuitive because it was designed specifically to model REST concepts, so a server is a Server, a method is a Method, a Request is a request, etc. And because this app is a Groovy script, we can use inline class definitions, and the syntax is nice and clean and easy.

I particularly like that Groovy maps the == operator to “value equality” as opposed to “identity equality” as in Java. The Java equivalent of line 16 would be:

if (request.getMethod().equals(Method.GET))

This also illustrates Groovy’s automatic getter referencing: to retrieve the method of the request, in Groovy I can use the syntax request.method, and Groovy automatically converts it into request.getMethod(). Nice!

Up and Running

Unices

$ chmod +x restfulapp.groovy
$ ./restfulapp.groovy

Windows

Launch a command prompt window, navigate to restfulapp, and run the command:

groovy -classpath org.restlet.jar;com.noelios.restlet.jar restfulapp.groovy

Test!

If you have cURL installed, you can run a quick ad-hoc test with the following command:

curl -v http://localhost:3000

But Groovy can make unit testing really easy:

Create a new file named testfulapp.groovy and copy the following code into it:

#!/usr/bin/env groovy -classpath org.restlet.jar:com.noelios.restlet.jar
import org.restlet.*
import org.restlet.data.*
client = new Client(Protocol.HTTP)
response = client.get("http://localhost:3000/")
assert response.status.code == 200
assert response.entity.mediaType.equals(MediaType.TEXT_PLAIN, true)
assert response.entity.size == 13
assert response.entity.text == "Hello, world!"
println "\nAll tests passed successfully!\n"

Open a new command prompt window, alongside the one already running restfulapp.groovy, and run testfulapp.groovy using the same steps outlined above for restfulapp.groovy for your OS. If all goes well, you should see “All tests passed successfully!” as the result!

Performance

Just for fun, if you’ve got a copy of ab installed:

ab -c 2 -t 10 http://localhost:3000/

Any numbers you see from ab can only be compared to your own, because everyone’s hardware and software varies, but it’s still fun to try pounding on your code and see what happens. I got 713 requests per second on my 2.2 GHz Santa Rosa Core 2 Duo MacBook, on OS X 10.5.3 and Java 1.5.0_13 – not bad!

That’s all, folks!

And that’s all for now. I hope this has been interesting and/or informative. I’d love to hear some feedback from readers: has this article made you interested in learning more about Groovy and/or Restlet?

Coming soon: Part 2: Resources.

Update, June 13th: Just published Part 2: Resources.

10 Responses

  1. Joshua Purcell said:

    Thanks for the article… I found out about it from your post on the rest-discuss mailing list. I haven’t used Groovy yet but I’m interested after seeing how straightforward this example is. I’m looking forward to further articles around combining Restlet and Groovy.

  2. Avi Flax said:

    @Joshua: My pleasure, I’m glad you liked it! I’m working on Part 2 right now, I hope you subscribed to our feed! Please keep the feedback coming – and any constructive criticism would be welcomed.

  3. Indy Nagpal said:

    Cheers. A very nice introduction.

  4. K said:

    Nice writing-up. Maybe you could also take a look at http://groovy.codehaus.org/GroovyRestlet, which is a simple DSL for construction restlet component using Groovy Markup syntax.

  5. Avi Flax said:

    @Indy: thanks!
    @K: Interesting, thanks for the link! One of my goals with this series is to introduce my team to Restlet’s class model and API, and to demonstrate how Groovy makes Java smoother and easier. So I don’t think the DSL is directly relevant to that. But it is an interesting way to approach the rapid construction of RESTful web apps.

  6. Brandon Franklin said:

    Hi. This is a good article, and I love the notion of combining Groovy and Restlet. However, I wonder if it’s really worth the time when you have Grails available. Are you familiar with Grails?
    http://www.grails.org
    Doing RESTful web services in Grails is even easier, I would posit. Especially check this out:
    http://grails.org/doc/1.0.x/guide/13.%20Web%20Services.html#13.1%20REST

  7. Avi Flax said:

    @Brandon: Thanks for the feedback! I am a little familiar with Grails, insofar as I know of RoR and Groovy, and knew that Grails existed.
    I would say that doing RESTful web services in Grails can be easier — if the service one wants to build fits into Grails’ conceptual model. If one wants to build a service which differs from Grails’ model, then it might be a more even matchup.
    There are two main reasons why I prefer Restlet to Grails:

    Grails, like RoR, seems to equate REST with CRUD. REST is not CRUD. (Related: REST is not just file storage)
    Grails enforces MVC. If one likes MVC, that’s great. But I’m not sold on it.

    I prefer Restlet because it doesn’t enforce any models other than REST itself, and it doesn’t push the mistaken idea that REST is CRUD – if anything, it encourages developers to think RESTfully, and to consider which representations a resource should expose, and how to expose them.
    Have you read Part 2 of this series yet? It goes further in demonstrating the Restlet model.

  8. Brian Alexander said:

    Hi Avi. Thanks for the article, but your statements about Grails in the previous comment are not entirely accurate. Grails has an elegant MVC architecture but you are in no way forced to use it. You are free to use controllers to handle requests without using GORM (M) or GSP (V).
    And Grails in no way confuses REST and CRUD (although certain Grails/Rails tutorials on the web may). The following shows an example URL mapping for a RESTful interface:
    static mappings = {
    “/message/$messageId?”(controller:”mailbox”){
    action = [GET:"handleGet", PUT:"handlePut", DELETE:"handleDelete", POST:"handlePost"]
    }
    }
    Grails has excellent support for content negotiation (http://grails.org/doc/1.0.x/guide/6.%20The%20Web%20Layer.html#6.8%20Content%20Negotiation), as well as several tools for rendering your representation. In addition to being able to render a string or write directly to an OutputStream, you can also use automatic XML/JSON marshalling, XML/JSON/HTML/RSS/Atom builders, or GSP.

  9. Niko Schmuck said:

    Avi: many thanks for starting such a great article series!
    Regarding the discussion using REST in Grails, wouldn’t it be possible to leverage both the elegance of RESTlet together with the (non-MVC) sugar of Grails? I think there are still so many benefits from using Grails (like the runtime environment, auto re-compile, GORM) that a combination might be interesting.
    What do you think?

  10. jdporter said:

    Avi, thanks for the great articles. I for one agree with any resistance to Grails. Not that Grails is in any way bad, in itself, but sometimes one needs to start out with something simpler.
    I’m wondering if you would consider updating for restlet 1.2. It seems that the lib contents have changed signficantly since 1.1. E.g. the com.noelios jars are not included.
    cheers,
    jdp

Leave a Comment