Running Ratpack inside Grails
When I would present on Ratpack at conferences, one of the main questions I'd get would be around the migration path from Ratpack to Grails. I'd usually answer noting that you could run Ratpack along side Grails. It turns out it is incredibly simple to run a Ratpack app inside Grails. I don't think it's a long term solution and best as an intermediary step to migrate from one side to the other.
1. Grab and build Ratpack.
Provided you already have Gradle installed, run gradle buildDistro. The only file you need is the main Ratpack-x.x file. Grails will provide the Groovy and servlet container run time for you. Add this to the lib directory of your Grails app.
2. Create your Ratpack app class.
Putting the script into a proper class, as shown below, makes it easier to reference it from our Servlet.
import java.text.SimpleDateFormat
import com.bleedingwolf.ratpack.*
class SampleApp {
def app = Ratpack.app {
set 'port', 4999
get("/") {
def ua = headers['user-agent']
"Your user-agent: ${ua} from Ratpack"
}
get("/foo/:name") {
"Hello, ${urlparams.name}"
}
get("/person/:id") {
"Person #${urlparams.id}"
}
}
public static void main(String[] args) {
SampleServlet.serve(new SampleApp().app)
}
}
3. Subclass RatpackServlet.
If you don't mind getting an logging error, you can use something as simple as the following file:
class SampleServlet extends RatpackServlet {
void init() {
app = new SampleApp().app
}
}
4. Add the servlet information to your application.
There is a really confusing way to do it using the resources.groovy file but I prefer just adding it to the web.xml by hand. Run
grails install-templates
and navigate to src/templates/war/web.xml and add the following:
<servlet>
<servlet-name>SampleServlet</servlet-name>
<servlet-class>SampleServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SampleServlet</servlet-name>
<url-pattern>/ratpack/*</url-pattern>
</servlet-mapping>
The servlet needs to be put on a url-pattern that isn't root (/*) so I used (/ratpack/*). Run *grails run-app *and you're all set.