Spring Boot with the Asset-Pipeline

Posted by David Estes on Dec 21, 2014

Filed under Open Source, Spring Boot, Groovy

During my off hours this week, I started playing around with spring-boot. This is one of those frameworks I've been meaning to learn and try out but haven't had the time until recently. My first impressions were fairly positive, though it can be tough to develop in with a simple editor like Sublime Text due to remembering the import statements for all those annotations.

One thing that caught me off guard was the limited support for serving static assets and dealing with compiling things like CoffeeScript or LESS. While it does provide support for customizing this behavior I felt a bit confused. Then again I'm kinda used to the asset-pipeline at this point :).

So, In building my prototype websocket based app in Spring Boot, I decided to further test out and develop the asset-pipelne support for it. You can actually see my prototype chat app that uses CoffeeScript, LESS, and HandlebarsJs. It can be found here. Currently I'm only messing with gradle support but it is entirely feasible to translate this to other build tools.

So How Does it work?

After getting your base spring-boot gradle build file (you can use start.spring.io if you want) we need to do a few things to get setup.

1. Add asset-pipeline-gradle to your buildscript.

buildscript {
    dependencies {
      classpath 'com.bertramlabs.plugins:asset-pipeline-gradle:2.0.19'
    }
}

apply plugin: 'asset-pipeline'

2. Configure asset-pipeline and jar task for assemble mode.

assets {
    compileDir = "${buildDir}/assetCompile/assets"
}

jar {
    from "${buildDir}/assetCompile"
}

3. Add asset-pipeline-spring-boot to runtime dependencies

dependencies {
    compile 'com.bertramlabs.plugins:asset-pipeline-spring-boot:2.0.19'
}

4. Create an assets folder with the following structure:

./assets/javascripts/
./assets/stylesheets/
./assets/images/

5. Add classpath to your applications @ComponentScan annotation

@ComponentScan(['asset.pipeline.springboot'])

Now you are all setup to use the asset-pipeline! The gradle plugin will automatically add itself to the gradle assemble task and precompile your assets into your jar file. The inclusion of the spring-boot adapter will allow you to work with the files in both development and production mode. It will provide ETag headers, gzip serving, and cache digest support.

You can make a file called ./assets/javascripts/application.js:

//= require jquery
//= require_tree .
//= require_self

console.log("Loaded");

Or a Css File called ./assets/stylesheets/application.css:

/*
*= require bootstrap
*= require nav
*= require_self
*/

For those unfamiliar with the asset-pipeline, the first folder structure in the assets folder gets flattened. So each of these files will be accessible from the urls /assets/application.js and /assets/application.css respectively. You can also define your own subfolders, the names do not matter. It is purely for your organizational benefit.

Now we want to use them in our templates. In my example app I'm using Thymeleaf. I have not yet created the various helpers for swapping asset references out with cache digest names for the various spring boot template libraries. However, the ETag headers do get used when requesting the file without its Digest name and seem to help ensure cache expiration well enough. So as long as you use the /assets url mapping you can include files directly in your template just like so:

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <script type="text/javascript" src="/assets/application.js"></script>
    <link rel="stylesheet" href="/assets/application.css"/>
</head>
<body>

</body>
</html>

I know there are a lot of configuration steps to get up and going with asset-pipeline and spring-boot. This is something I hope to remedy and encourage contributions on. You can find the source code to the spring-boot and gradle adapter in the subfolders of the asset-pipeline-core repository.

Developing with Spring Boot started getting a lot more interesting after getting this hurdle out of the way. I was able to play a bit more with websockets and the general runtime of spring-boot itself.

Feel free to check out my above mentioned sample chat app to see the asset-pipeline in action for spring boot and feedback is definitely welcome.