Sunday, January 29, 2012

Grails and Ratpack

Today I've found out about the Ratpack plugin. Being a huge Sinatra fan I was quite fond of the Ratpack framework to begin with and naturally I was amazed to see it incorporated into Grails as a plugin. And it works!

Let me walk you through a very simple example of using Ratpack inside Grails.

We start by enabling the Ratpack plugin in our application. I called mine app "example" so all the URLs will be prefixed with "/example". To include the plugin you need to add it to grails-app/conf/BuildConfig.groovy like this:

With that in place we'll create a domain class to have some data to display. I'll go with the simplest possible class that represents a person grails-app/domain/Person.groovy:

Simple enough, right? Let's go an make some use of it in a Ratpack file. Create a folder grails-app/ratpack and inside of it a file called PersonRatpack.groovy:

As you can see here all we're doing is responding to the GET method on some root URL. Ratpack uses SimpleTemplateEngine from Groovy. We have to tell it where to look for templates Config.groovy:

So let's create one to display the people from database grails-app/ratpack/templates/list.html:

Simple enough, right? It almost looks like a mix of ERB and expression language from JSP. I think you'd have to ask the authors of SimpleTemplateEngine if those similarities have been made on purpose of if this syntax just seemed to be the only one that made sense...

Anyways, with all that in place we can add some people to the database in our grails-app/conf/BootStrap.groovy file like this:

And that's it! start the application, navigate to http://localhost:8080/example/ratpack and you should see the list of two people on the screen.

Needless to say you can accomplish the exact same thing using a controller and a view. The idea here however is to show you that there is life beyond the standard artifacts and that the beauty lies in diversity!

Hope this will help someone get started with this awesome piece of code!

5 comments:

Matthias Hryniszak said...

This solution doesn't work when deploying the application as WAR file. Does anyone knows how to make it work in deployment?

Marcin Niebudek said...

Maybe a build dependency instead of compile one? But it's just a wild unverified guess.

I wanted to tell something else. I've learned about this integration today too and as far as I see the case for using Ratpack with pure Groovy to build a very simple webapp exposing for example 1 or 2 services through the REST API and not needing the full Grails stack, at the same time I don't actually get why would I need that in Grails?

I don't find diversity as an advantage. Much more I prefer convention especially if using separate URL mappings and templates instead of views may cause unwanted mess in the project.

I can actually think about one case which is exposing a REST API through Ratpack for a fully featured application where base controllers provide normal workflow based on views and Ratpack can provide a eparate RESTfull layer in the /api/* URL space and reuse the common services.

But I'm not yet sure if this would be the best solution in Grails. Anyway all the lightness of Ratpack is lost in Grails. What do you think? I'd love to hear about hat is it good for in Grails?

Matthias Hryniszak said...

See there are different technologies available on the OpenSource market today. There's Wicket, JSF(2), Sinatra and imitators. I think they all have their place in the overall landscape. What I find particularly interesting is having one base to build upon (Grails) with additional technologies supporting all the goodness whatever way they can - and wherever it makes sense.

Like I said in the blog at first you could easily do the exact same thing using a standard controller and a view - but somehow I find Ratpack amusing enough to try it out...

Burt said...

Great post - thanks for doing the writeup. I released version 1.0.1 which fixes the problem with templates in a war file - see the plugin page for how to configure it: http://grails.org/plugin/ratpack

Matthias Hryniszak said...

@Burt Thanks! I've updated the gist with example.